111 lines
11 KiB
Markdown
111 lines
11 KiB
Markdown
<!-- file: docs/SPL_TOKEN2022_CONFIDENTIAL_EXECUTION_AUDIT.md -->
|
||
<!-- version: 6 -->
|
||
|
||
# Audit d’exécution Confidential Transfer Token-2022
|
||
|
||
## Frontières de programme
|
||
|
||
Les instructions Confidential Transfer restent des instructions du programme Token-2022. Les preuves associées sont des instructions distinctes du programme natif ZK ElGamal Proof ou des comptes de contexte déjà vérifiés. Le registre ElGamal reste une troisième surface avec son propre Program ID.
|
||
|
||
Aucun builder Token-2022 ne doit incorporer silencieusement une preuve, déchiffrer un solde ou générer une clé privée.
|
||
|
||
## Modes de preuve
|
||
|
||
Chaque preuve est fournie selon un seul mode explicite :
|
||
|
||
- `instruction_offset` : offset relatif signé non nul vers une instruction ZK distincte de la même transaction ;
|
||
- `context_state_account` : compte readonly contenant le contexte public d’une preuve déjà vérifiée ; le wire Token-2022 encode alors l’offset `0`.
|
||
|
||
Un offset inline égal à zéro est invalide dans le contrat de l’exécuteur, car il rendrait le mode ambigu.
|
||
|
||
## Inventaire audité
|
||
|
||
| Opération | Preuves ordonnées | Classe d’exécution |
|
||
|-------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
|
||
| InitializeMint | aucune | builder public |
|
||
| UpdateMint | aucune | builder public |
|
||
| ConfigureAccount | PubkeyValidity | entrées cryptographiques appelant |
|
||
| ApproveAccount | aucune | builder public |
|
||
| EmptyAccount | ZeroCiphertext | entrées cryptographiques appelant |
|
||
| Deposit | aucune | builder public |
|
||
| Withdraw | CiphertextCommitmentEquality, BatchedRangeProofU64 | entrées cryptographiques appelant |
|
||
| Transfer | CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, BatchedRangeProofU128 | entrées cryptographiques appelant |
|
||
| ApplyPendingBalance | aucune | builder public |
|
||
| EnableConfidentialCredits | aucune | builder public |
|
||
| DisableConfidentialCredits | aucune | builder public |
|
||
| EnableNonConfidentialCredits | aucune | builder public |
|
||
| DisableNonConfidentialCredits | aucune | builder public |
|
||
| TransferWithFee | CiphertextCommitmentEquality, BatchedGroupedCiphertext3HandlesValidity, PercentageWithFee, BatchedGroupedCiphertext2HandlesValidity, BatchedRangeProofU256 | entrées cryptographiques appelant |
|
||
| ConfigureAccountWithRegistry | PubkeyValidity | entrées cryptographiques appelant |
|
||
|
||
La classe « builder public » signifie seulement que l’instruction Token-2022 ne nécessite pas de ciphertext ou preuve nouvellement généré. Elle ne dispense ni du préflight, ni de la simulation, ni des autorités et postconditions.
|
||
|
||
## Plan de livraison
|
||
|
||
- `pre.048` : types, modes de preuve, ordre des preuves et classification de support ;
|
||
- `pre.049` : builders publics Initialize/Update/Approve/Deposit/Apply/credit toggles ;
|
||
- `pre.050` : clés ElGamal et balances déchiffrables opaques, Initialize/Update Mint et Apply Pending Balance ;
|
||
- `pre.051` : Configure Account et Configure Account With Registry ;
|
||
- `pre.052` : Empty Account avec preuve ZeroCiphertext inline ou context-state ;
|
||
- `pre.053` : Withdraw avec Equality et Range U64 ;
|
||
- `pre.054` : Transfer avec Equality, Grouped Ciphertext Validity à trois handles et Range U128 ;
|
||
- `pre.055` : audit exact de Transfer With Fee, cinq preuves, comptes et payload ;
|
||
- `pre.056` : builder Transfer With Fee ;
|
||
- tranches ultérieures : Confidential Transfer Fee, Confidential Mint/Burn et Permissioned Confidential Burn.
|
||
|
||
## `pre.053` — Withdraw
|
||
|
||
`Withdraw` exige deux références de preuve dans l’ordre officiel : `CiphertextCommitmentEquality`, puis `BatchedRangeProofU64`. Les modes inline et context-state peuvent être combinés. L’exécuteur transporte la nouvelle balance déchiffrable opaque sans produire ni vérifier localement les secrets ou preuves.
|
||
|
||
|
||
## `pre.054` — Transfer
|
||
|
||
`Transfer` transporte une nouvelle balance source déchiffrable de 36 octets et deux ciphertexts auditeur ElGamal de 64 octets. Il exige exactement trois références de preuve dans l'ordre officiel : `CiphertextCommitmentEquality`, `BatchedGroupedCiphertext3HandlesValidity`, puis `BatchedRangeProofU128`. Chaque preuve peut être inline ou context-state ; l'Instructions Sysvar n'est ajouté qu'une fois lorsqu'au moins un offset est utilisé. Aucune donnée cryptographique n'est générée par l'exécuteur.
|
||
|
||
|
||
## `pre.055` — audit Transfer With Fee
|
||
|
||
`TransferWithFee` conserve le même payload cryptographique Token-2022 que `Transfer` : une balance source déchiffrable de 36 octets et deux ciphertexts auditeur ElGamal de 64 octets. Il n’ajoute pas de ciphertext withheld ou de montant de frais au payload Token-2022. Les informations de frais et le ciphertext de frais appartiennent aux contextes publics des preuves `PercentageWithFee` et `BatchedGroupedCiphertext2HandlesValidity`.
|
||
|
||
Le wire exact contient le tag externe `27`, le sous-tag `13`, puis 169 octets de payload : `36 + 64 + 64 + 5 offsets i8`. La donnée complète mesure donc 171 octets.
|
||
|
||
Les cinq preuves restent ordonnées :
|
||
|
||
1. `CiphertextCommitmentEquality` ;
|
||
2. `BatchedGroupedCiphertext3HandlesValidity` pour le montant transféré ;
|
||
3. `PercentageWithFee` ;
|
||
4. `BatchedGroupedCiphertext2HandlesValidity` pour le ciphertext de frais ;
|
||
5. `BatchedRangeProofU256`.
|
||
|
||
L’ordre des comptes est source writable, mint readonly, destination writable, Instructions Sysvar si au moins une preuve est inline, comptes context-state dans l’ordre des cinq preuves, autorité, puis signataires multisig. Aucun type opaque Token-2022 supplémentaire n’est nécessaire avant le builder de `pre.056`.
|
||
|
||
## Builder Transfer With Fee — pre.056
|
||
|
||
Le builder `inner_transfer_with_fee` est activé avec les cinq preuves dans l’ordre officiel. Le payload reste limité à la nouvelle balance déchiffrable, aux deux ciphertexts auditeur et aux cinq offsets. Les comptes context-state suivent le même ordre que les preuves et l’Instructions Sysvar n’est présent qu’une fois lorsqu’au moins un offset inline est utilisé.
|
||
|
||
## Confidential Transfer Fee public builder tranche (`pre.057`)
|
||
|
||
The proof-free builder surface is restricted to subdiscriminants 0, 3, 4 and 5
|
||
of the Token-2022 `ConfidentialTransferFeeExtension` envelope (external tag 37).
|
||
Initialization accepts one writable mint, an optional configuration authority
|
||
and one exact 32-byte ElGamal public key. Enable/disable harvest preserve simple
|
||
or multisig authority metas. Permissionless harvest preserves an ordered,
|
||
non-empty, duplicate-free source list bounded to 255 accounts. Withdrawals remain
|
||
separate because they require ciphertext-equality proof context.
|
||
|
||
## Confidential Transfer Fee — retrait depuis plusieurs comptes (`pre.059`)
|
||
|
||
Le builder `inner_withdraw_withheld_tokens_from_accounts` conserve l’ordre officiel suivant : Mint readonly, destination writable, Instructions Sysvar ou compte context-state, autorité withdraw-withheld, signataires multisig, puis sources writable. Le payload encode `num_token_accounts: u8`, l’offset de preuve et la nouvelle balance déchiffrable destination.
|
||
|
||
La preuve requise est `CiphertextCiphertextEquality`. La liste des sources est non vide, unique, ordonnée et limitée à 255 comptes. Cette opération est explicitement sensible au front-running : une mutation d’un withheld ciphertext source après génération de la preuve fait échouer la transaction. Le parcours harvest-vers-Mint puis retrait-depuis-Mint reste l’alternative recommandée lorsque la stabilité des comptes sources ne peut pas être garantie.
|
||
|
||
## `pre.060` — audit Confidential Mint/Burn
|
||
|
||
L'interface publie six sous-instructions contiguës : `InitializeMint = 0`, `RotateSupplyElGamalPubkey = 1`, `UpdateDecryptableSupply = 2`, `Mint = 3`, `Burn = 4` et `ApplyPendingBurn = 5`. Cette famille reste dans l'enveloppe Token-2022 Confidential Mint/Burn et ne doit pas être confondue avec Permissioned Burn.
|
||
|
||
`InitializeMint` transporte une clé publique ElGamal de supply et une supply déchiffrable initiale. `RotateSupplyElGamalPubkey` transporte la nouvelle clé et exige `CiphertextCiphertextEquality`. `UpdateDecryptableSupply` et `ApplyPendingBurn` n'exigent aucune preuve, mais restent soumis aux autorités et préconditions d'état.
|
||
|
||
`Mint` et `Burn` exigent exactement trois preuves dans l'ordre : `CiphertextCommitmentEquality`, `BatchedGroupedCiphertext3HandlesValidity`, puis `BatchedRangeProofU128`. Les deux opérations transportent deux ciphertexts auditeur ; `Mint` transporte la nouvelle supply déchiffrable, tandis que `Burn` transporte la nouvelle balance disponible déchiffrable du compte source. Aucun secret, ciphertext ou preuve n'est généré par l'exécuteur.
|
||
|
||
Le découpage prévu est : builders publics et rotation dans `pre.061`, puis Mint/Burn prouvés dans `pre.062`. Permissioned Confidential Burn reste une tranche indépendante.
|