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

Commit 95b889e

Browse files
committed
add auditor ciphertext to confidential mint and burn instruction data
1 parent 0f36ed8 commit 95b889e

File tree

4 files changed

+85
-26
lines changed

4 files changed

+85
-26
lines changed

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use {
1616
program_error::ProgramError,
1717
pubkey::Pubkey,
1818
},
19-
solana_zk_sdk::encryption::pod::{auth_encryption::PodAeCiphertext, elgamal::PodElGamalPubkey},
19+
solana_zk_sdk::encryption::pod::{
20+
auth_encryption::PodAeCiphertext,
21+
elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
22+
},
2023
};
2124
#[cfg(not(target_os = "solana"))]
2225
use {
@@ -229,6 +232,12 @@ pub struct MintInstructionData {
229232
/// The new decryptable supply if the mint succeeds
230233
#[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
231234
pub new_decryptable_supply: PodAeCiphertext,
235+
/// The transfer amount encrypted under the auditor ElGamal public key
236+
#[cfg_attr(feature = "serde-traits", serde(with = "elgamalciphertext_fromstr"))]
237+
pub mint_amount_auditor_ciphertext_lo: PodElGamalCiphertext,
238+
/// The transfer amount encrypted under the auditor ElGamal public key
239+
#[cfg_attr(feature = "serde-traits", serde(with = "elgamalciphertext_fromstr"))]
240+
pub mint_amount_auditor_ciphertext_hi: PodElGamalCiphertext,
232241
/// Relative location of the
233242
/// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction
234243
/// to the `ConfidentialMint` instruction in the transaction. 0 if the
@@ -254,6 +263,12 @@ pub struct BurnInstructionData {
254263
/// The new decryptable balance of the burner if the burn succeeds
255264
#[cfg_attr(feature = "serde-traits", serde(with = "aeciphertext_fromstr"))]
256265
pub new_decryptable_available_balance: DecryptableBalance,
266+
/// The transfer amount encrypted under the auditor ElGamal public key
267+
#[cfg_attr(feature = "serde-traits", serde(with = "elgamalciphertext_fromstr"))]
268+
pub burn_amount_auditor_ciphertext_lo: PodElGamalCiphertext,
269+
/// The transfer amount encrypted under the auditor ElGamal public key
270+
#[cfg_attr(feature = "serde-traits", serde(with = "elgamalciphertext_fromstr"))]
271+
pub burn_amount_auditor_ciphertext_hi: PodElGamalCiphertext,
257272
/// Relative location of the
258273
/// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction
259274
/// to the `ConfidentialMint` instruction in the transaction. 0 if the
@@ -391,6 +406,8 @@ pub fn confidential_mint_with_split_proofs(
391406
token_account: &Pubkey,
392407
mint: &Pubkey,
393408
supply_elgamal_pubkey: Option<ElGamalPubkey>,
409+
mint_amount_auditor_ciphertext_lo: &PodElGamalCiphertext,
410+
mint_amount_auditor_ciphertext_hi: &PodElGamalCiphertext,
394411
authority: &Pubkey,
395412
multisig_signers: &[&Pubkey],
396413
equality_proof_location: ProofLocation<CiphertextCommitmentEqualityProofData>,
@@ -455,6 +472,8 @@ pub fn confidential_mint_with_split_proofs(
455472
ConfidentialMintBurnInstruction::Mint,
456473
&MintInstructionData {
457474
new_decryptable_supply: new_decryptable_supply.into(),
475+
mint_amount_auditor_ciphertext_lo: *mint_amount_auditor_ciphertext_lo,
476+
mint_amount_auditor_ciphertext_hi: *mint_amount_auditor_ciphertext_hi,
458477
equality_proof_instruction_offset,
459478
ciphertext_validity_proof_instruction_offset,
460479
range_proof_instruction_offset,
@@ -475,6 +494,8 @@ pub fn confidential_burn_with_split_proofs(
475494
mint: &Pubkey,
476495
supply_elgamal_pubkey: Option<ElGamalPubkey>,
477496
new_decryptable_available_balance: DecryptableBalance,
497+
burn_amount_auditor_ciphertext_lo: &PodElGamalCiphertext,
498+
burn_amount_auditor_ciphertext_hi: &PodElGamalCiphertext,
478499
authority: &Pubkey,
479500
multisig_signers: &[&Pubkey],
480501
equality_proof_location: ProofLocation<CiphertextCommitmentEqualityProofData>,
@@ -537,6 +558,8 @@ pub fn confidential_burn_with_split_proofs(
537558
ConfidentialMintBurnInstruction::Burn,
538559
&BurnInstructionData {
539560
new_decryptable_available_balance,
561+
burn_amount_auditor_ciphertext_lo: *burn_amount_auditor_ciphertext_lo,
562+
burn_amount_auditor_ciphertext_hi: *burn_amount_auditor_ciphertext_hi,
540563
equality_proof_instruction_offset,
541564
ciphertext_validity_proof_instruction_offset,
542565
range_proof_instruction_offset,

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

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use spl_token_confidential_transfer_ciphertext_arithmetic as ciphertext_arithmetic;
33
use {
44
crate::{
5-
check_program_account,
5+
check_auditor_ciphertext, check_program_account,
66
error::TokenError,
77
extension::{
88
confidential_mint_burn::{
@@ -210,20 +210,36 @@ fn process_confidential_mint(
210210
}
211211
}
212212

213+
let proof_context_auditor_ciphertext_lo = proof_context
214+
.mint_amount_ciphertext_lo
215+
.try_extract_ciphertext(2)
216+
.map_err(|e| -> TokenError { e.into() })?;
217+
let proof_context_auditor_ciphertext_hi = proof_context
218+
.mint_amount_ciphertext_hi
219+
.try_extract_ciphertext(2)
220+
.map_err(|e| -> TokenError { e.into() })?;
221+
222+
check_auditor_ciphertext(
223+
&data.mint_amount_auditor_ciphertext_lo,
224+
&data.mint_amount_auditor_ciphertext_hi,
225+
&proof_context_auditor_ciphertext_lo,
226+
&proof_context_auditor_ciphertext_hi,
227+
)?;
228+
213229
confidential_transfer_account.pending_balance_lo = ciphertext_arithmetic::add(
214230
&confidential_transfer_account.pending_balance_lo,
215231
&proof_context
216232
.mint_amount_ciphertext_lo
217233
.try_extract_ciphertext(0)
218-
.map_err(|_| ProgramError::InvalidAccountData)?,
234+
.map_err(|e| -> TokenError { e.into() })?,
219235
)
220236
.ok_or(TokenError::CiphertextArithmeticFailed)?;
221237
confidential_transfer_account.pending_balance_hi = ciphertext_arithmetic::add(
222238
&confidential_transfer_account.pending_balance_hi,
223239
&proof_context
224240
.mint_amount_ciphertext_hi
225241
.try_extract_ciphertext(0)
226-
.map_err(|_| ProgramError::InvalidAccountData)?,
242+
.map_err(|e| -> TokenError { e.into() })?,
227243
)
228244
.ok_or(TokenError::CiphertextArithmeticFailed)?;
229245

@@ -311,14 +327,30 @@ fn process_confidential_burn(
311327
return Err(TokenError::ConfidentialTransferElGamalPubkeyMismatch.into());
312328
}
313329

330+
let proof_context_auditor_ciphertext_lo = proof_context
331+
.burn_amount_ciphertext_lo
332+
.try_extract_ciphertext(2)
333+
.map_err(|e| -> TokenError { e.into() })?;
334+
let proof_context_auditor_ciphertext_hi = proof_context
335+
.burn_amount_ciphertext_hi
336+
.try_extract_ciphertext(2)
337+
.map_err(|e| -> TokenError { e.into() })?;
338+
339+
check_auditor_ciphertext(
340+
&data.burn_amount_auditor_ciphertext_lo,
341+
&data.burn_amount_auditor_ciphertext_hi,
342+
&proof_context_auditor_ciphertext_lo,
343+
&proof_context_auditor_ciphertext_hi,
344+
)?;
345+
314346
let burn_amount_lo = &proof_context
315347
.burn_amount_ciphertext_lo
316348
.try_extract_ciphertext(0)
317-
.map_err(|_| ProgramError::InvalidAccountData)?;
349+
.map_err(|e| -> TokenError { e.into() })?;
318350
let burn_amount_hi = &proof_context
319351
.burn_amount_ciphertext_hi
320352
.try_extract_ciphertext(0)
321-
.map_err(|_| ProgramError::InvalidAccountData)?;
353+
.map_err(|e| -> TokenError { e.into() })?;
322354

323355
let new_source_available_balance = ciphertext_arithmetic::subtract_with_lo_hi(
324356
&confidential_transfer_account.available_balance,

token/program-2022/src/extension/confidential_transfer/processor.rs

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use {
77
};
88
use {
99
crate::{
10-
check_elgamal_registry_program_account, check_program_account,
10+
check_auditor_ciphertext, check_elgamal_registry_program_account, check_program_account,
1111
error::TokenError,
1212
extension::{
1313
confidential_transfer::{instruction::*, verify_proof::*, *},
@@ -801,23 +801,6 @@ fn process_transfer(
801801
Ok(())
802802
}
803803

804-
/// Check instruction data and proof data auditor ciphertext consistency
805-
#[cfg(feature = "zk-ops")]
806-
fn check_auditor_ciphertext(
807-
instruction_data_auditor_ciphertext_lo: &PodElGamalCiphertext,
808-
instruction_data_auditor_ciphertext_hi: &PodElGamalCiphertext,
809-
proof_context_auditor_ciphertext_lo: &PodElGamalCiphertext,
810-
proof_context_auditor_ciphertext_hi: &PodElGamalCiphertext,
811-
) -> ProgramResult {
812-
if instruction_data_auditor_ciphertext_lo != proof_context_auditor_ciphertext_lo {
813-
return Err(TokenError::ConfidentialTransferBalanceMismatch.into());
814-
}
815-
if instruction_data_auditor_ciphertext_hi != proof_context_auditor_ciphertext_hi {
816-
return Err(TokenError::ConfidentialTransferBalanceMismatch.into());
817-
}
818-
Ok(())
819-
}
820-
821804
/// Processes the changes for the sending party of a confidential transfer
822805
#[cfg(feature = "zk-ops")]
823806
fn process_source_for_transfer(

token/program-2022/src/lib.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ mod entrypoint;
2323

2424
// Export current sdk types for downstream users building with a different sdk
2525
// version
26-
use solana_program::{
27-
entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, system_program,
26+
use {
27+
error::TokenError,
28+
solana_program::{
29+
entrypoint::ProgramResult, program_error::ProgramError, pubkey::Pubkey, system_program,
30+
},
31+
solana_zk_sdk::encryption::pod::elgamal::PodElGamalCiphertext,
2832
};
2933
pub use {solana_program, solana_zk_sdk};
3034

@@ -139,3 +143,20 @@ pub(crate) fn check_elgamal_registry_program_account(
139143
}
140144
Ok(())
141145
}
146+
147+
/// Check instruction data and proof data auditor ciphertext consistency
148+
#[cfg(feature = "zk-ops")]
149+
pub(crate) fn check_auditor_ciphertext(
150+
instruction_data_auditor_ciphertext_lo: &PodElGamalCiphertext,
151+
instruction_data_auditor_ciphertext_hi: &PodElGamalCiphertext,
152+
proof_context_auditor_ciphertext_lo: &PodElGamalCiphertext,
153+
proof_context_auditor_ciphertext_hi: &PodElGamalCiphertext,
154+
) -> ProgramResult {
155+
if instruction_data_auditor_ciphertext_lo != proof_context_auditor_ciphertext_lo {
156+
return Err(TokenError::ConfidentialTransferBalanceMismatch.into());
157+
}
158+
if instruction_data_auditor_ciphertext_hi != proof_context_auditor_ciphertext_hi {
159+
return Err(TokenError::ConfidentialTransferBalanceMismatch.into());
160+
}
161+
Ok(())
162+
}

0 commit comments

Comments
 (0)