Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 5380b0e

Browse files
[program-2022] Add functions to generate mint/burn proofs from account info (#7575)
1 parent 551931d commit 5380b0e

File tree

3 files changed

+108
-12
lines changed

3 files changed

+108
-12
lines changed

token/confidential-transfer/proof-generation/src/mint.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use {
55
},
66
solana_zk_sdk::{
77
encryption::{
8-
auth_encryption::{AeCiphertext, AeKey},
98
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
109
pedersen::Pedersen,
1110
},
@@ -28,15 +27,13 @@ pub struct MintProofData {
2827
pub ciphertext_validity_proof_data_with_ciphertext:
2928
CiphertextValidityProofWithAuditorCiphertext,
3029
pub range_proof_data: BatchedRangeProofU128Data,
31-
pub new_decryptable_supply: AeCiphertext,
3230
}
3331

3432
pub fn mint_split_proof_data(
3533
current_supply_ciphertext: &ElGamalCiphertext,
3634
mint_amount: u64,
3735
current_supply: u64,
3836
supply_elgamal_keypair: &ElGamalKeypair,
39-
supply_aes_key: &AeKey,
4037
destination_elgamal_pubkey: &ElGamalPubkey,
4138
auditor_elgamal_pubkey: Option<&ElGamalPubkey>,
4239
) -> Result<MintProofData, TokenProofGenerationError> {
@@ -161,6 +158,5 @@ pub fn mint_split_proof_data(
161158
equality_proof_data,
162159
ciphertext_validity_proof_data_with_ciphertext,
163160
range_proof_data,
164-
new_decryptable_supply: supply_aes_key.encrypt(new_supply),
165161
})
166162
}

token/confidential-transfer/proof-tests/tests/proof_test.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,21 +222,18 @@ fn test_mint_validity(mint_amount: u64, supply: u64) {
222222
let auditor_pubkey = auditor_keypair.pubkey();
223223

224224
let supply_keypair = ElGamalKeypair::new_rand();
225-
let supply_aes_key = AeKey::new_rand();
226225

227226
let supply_ciphertext = supply_keypair.pubkey().encrypt(supply);
228227

229228
let MintProofData {
230229
equality_proof_data,
231230
ciphertext_validity_proof_data_with_ciphertext,
232231
range_proof_data,
233-
new_decryptable_supply: _,
234232
} = mint_split_proof_data(
235233
&supply_ciphertext,
236234
mint_amount,
237235
supply,
238236
&supply_keypair,
239-
&supply_aes_key,
240237
destination_pubkey,
241238
Some(auditor_pubkey),
242239
)

token/program-2022/src/extension/confidential_mint_burn/account_info.rs

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
use {
22
super::ConfidentialMintBurn,
3-
crate::error::TokenError,
3+
crate::{
4+
error::TokenError,
5+
extension::confidential_transfer::{
6+
ConfidentialTransferAccount, DecryptableBalance, EncryptedBalance,
7+
},
8+
},
49
bytemuck::{Pod, Zeroable},
510
solana_zk_sdk::{
611
encryption::{
712
auth_encryption::{AeCiphertext, AeKey},
8-
elgamal::{ElGamalCiphertext, ElGamalKeypair},
13+
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
914
pedersen::PedersenOpening,
1015
pod::{
1116
auth_encryption::PodAeCiphertext,
@@ -14,6 +19,10 @@ use {
1419
},
1520
zk_elgamal_proof_program::proof_data::CiphertextCiphertextEqualityProofData,
1621
},
22+
spl_token_confidential_transfer_proof_generation::{
23+
burn::{burn_split_proof_data, BurnProofData},
24+
mint::{mint_split_proof_data, MintProofData},
25+
},
1726
};
1827

1928
/// Confidential Mint Burn extension information needed to construct a
@@ -43,7 +52,7 @@ impl SupplyAccountInfo {
4352
/// Computes the current supply from the decryptable supply and the
4453
/// difference between the decryptable supply and the ElGamal encrypted
4554
/// supply ciphertext
46-
pub fn decrypt_current_supply(
55+
pub fn decrypted_current_supply(
4756
&self,
4857
aes_key: &AeKey,
4958
elgamal_keypair: &ElGamalKeypair,
@@ -77,12 +86,12 @@ impl SupplyAccountInfo {
7786
/// `RotateSupplyElgamalPubkey` instruction
7887
pub fn generate_rotate_supply_elgamal_pubkey_proof(
7988
&self,
80-
aes_key: &AeKey,
8189
current_supply_elgamal_keypair: &ElGamalKeypair,
8290
new_supply_elgamal_keypair: &ElGamalKeypair,
91+
aes_key: &AeKey,
8392
) -> Result<CiphertextCiphertextEqualityProofData, TokenError> {
8493
let current_supply =
85-
self.decrypt_current_supply(aes_key, current_supply_elgamal_keypair)?;
94+
self.decrypted_current_supply(aes_key, current_supply_elgamal_keypair)?;
8695

8796
let new_supply_opening = PedersenOpening::new_rand();
8897
let new_supply_ciphertext = new_supply_elgamal_keypair
@@ -102,4 +111,98 @@ impl SupplyAccountInfo {
102111
)
103112
.map_err(|_| TokenError::ProofGeneration)
104113
}
114+
115+
/// Create a mint proof data that is split into equality, ciphertext
116+
/// validity, and range proof.
117+
pub fn generate_split_mint_proof_data(
118+
&self,
119+
mint_amount: u64,
120+
current_supply: u64,
121+
supply_elgamal_keypair: &ElGamalKeypair,
122+
destination_elgamal_pubkey: &ElGamalPubkey,
123+
auditor_elgamal_pubkey: Option<&ElGamalPubkey>,
124+
) -> Result<MintProofData, TokenError> {
125+
let current_supply_ciphertext = self
126+
.current_supply
127+
.try_into()
128+
.map_err(|_| TokenError::MalformedCiphertext)?;
129+
130+
mint_split_proof_data(
131+
&current_supply_ciphertext,
132+
mint_amount,
133+
current_supply,
134+
supply_elgamal_keypair,
135+
destination_elgamal_pubkey,
136+
auditor_elgamal_pubkey,
137+
)
138+
.map_err(|e| -> TokenError { e.into() })
139+
}
140+
141+
/// Compute the new decryptable supply.
142+
pub fn new_decryptable_supply(
143+
&self,
144+
mint_amount: u64,
145+
elgamal_keypair: &ElGamalKeypair,
146+
aes_key: &AeKey,
147+
) -> Result<AeCiphertext, TokenError> {
148+
let current_decrypted_supply = self.decrypted_current_supply(aes_key, elgamal_keypair)?;
149+
let new_decrypted_available_balance = current_decrypted_supply
150+
.checked_add(mint_amount)
151+
.ok_or(TokenError::Overflow)?;
152+
153+
Ok(aes_key.encrypt(new_decrypted_available_balance))
154+
}
155+
}
156+
157+
/// Confidential Mint Burn extension information needed to construct a
158+
/// `Burn` instruction.
159+
#[repr(C)]
160+
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
161+
pub struct BurnAccountInfo {
162+
/// The available balance (encrypted by `encryption_pubkey`)
163+
pub available_balance: EncryptedBalance,
164+
/// The decryptable available balance
165+
pub decryptable_available_balance: DecryptableBalance,
166+
}
167+
168+
impl BurnAccountInfo {
169+
/// Create the `ApplyPendingBalance` instruction account information from
170+
/// `ConfidentialTransferAccount`.
171+
pub fn new(account: &ConfidentialTransferAccount) -> Self {
172+
Self {
173+
available_balance: account.available_balance,
174+
decryptable_available_balance: account.decryptable_available_balance,
175+
}
176+
}
177+
178+
/// Create a burn proof data that is split into equality, ciphertext
179+
/// validity, and range proof.
180+
pub fn generate_split_burn_proof_data(
181+
&self,
182+
burn_amount: u64,
183+
source_elgamal_keypair: &ElGamalKeypair,
184+
aes_key: &AeKey,
185+
supply_elgamal_pubkey: &ElGamalPubkey,
186+
auditor_elgamal_pubkey: Option<&ElGamalPubkey>,
187+
) -> Result<BurnProofData, TokenError> {
188+
let current_available_balance_ciphertext = self
189+
.available_balance
190+
.try_into()
191+
.map_err(|_| TokenError::MalformedCiphertext)?;
192+
let current_decryptable_available_balance = self
193+
.decryptable_available_balance
194+
.try_into()
195+
.map_err(|_| TokenError::MalformedCiphertext)?;
196+
197+
burn_split_proof_data(
198+
&current_available_balance_ciphertext,
199+
&current_decryptable_available_balance,
200+
burn_amount,
201+
source_elgamal_keypair,
202+
aes_key,
203+
auditor_elgamal_pubkey,
204+
supply_elgamal_pubkey,
205+
)
206+
.map_err(|e| -> TokenError { e.into() })
207+
}
105208
}

0 commit comments

Comments
 (0)