1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use ;
/// Confidential Mint-Burn Extension instructions
/// Confidential mint-burn mint configuration.
///
/// # Supply reconciliation
///
/// `decryptable_supply` is an AES-encrypted cache for the mint
/// authority's convenience. The program does not verify that it encrypts the
/// same value as `confidential_supply`.
///
/// `ApplyPendingBurn` subtracts the pending burns from `confidential_supply`
/// and clears `pending_burn`, but leaves `decryptable_supply` unchanged.
/// Callers do not need to submit a separate `UpdateDecryptableSupply` after
/// every `ApplyPendingBurn`. Instead, clients can recover the current supply
/// locally before generating mint or supply key rotation proofs:
///
/// 1. AES-decrypt `decryptable_supply` to obtain `cached_supply`.
/// 2. Encrypt `cached_supply` under `supply_elgamal_pubkey` to obtain
/// `Enc(cached_supply)`.
/// 3. Homomorphically subtract `confidential_supply` from
/// `Enc(cached_supply)`.
/// 4. Decrypt this difference with the supply ElGamal secret key to obtain
/// `applied_burns`.
/// 5. Compute `current_supply = cached_supply - applied_burns`.
///
/// When the cache was last set to the correct supply, this difference is the
/// total burns applied since that update. Decrypting differences of up to
/// about 40 bits is practical with a suitable discrete-log search, even when
/// the full supply is a `u64`. Larger differences become increasingly expensive
/// to decrypt and can make direct recovery impractical. In that case, clients
/// can recover `applied_burns` by decrypting individual burns from transaction
/// history.
///
/// Individual burn proofs split amounts into 16-bit low and 32-bit high
/// ciphertexts, but the program combines them into a single `pending_burn`
/// ciphertext. The mint state does not retain separate low/high ciphertexts
/// for decoding.
///
/// Submitting `ApplyPendingBurn` regularly limits the amount accumulating in
/// `pending_burn`. Periodically refreshing the supply cache with the reconciled
/// value also keeps `applied_burns` small and reduces decryption overhead.
///
/// For a mint, the client AES-encrypts `current_supply + mint_amount`
/// into `MintInstructionData::new_decryptable_supply`. A successful `Mint`
/// stores that value, refreshing the cache without a separate
/// `UpdateDecryptableSupply`. Supply key rotation leaves the cache unchanged.