From 4c96d82253296cc20d7f8a754ff3a5c798568aa8 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Fri, 7 Feb 2025 15:43:44 +0900 Subject: [PATCH 1/3] re-order confidential mint burn ciphertexts to dest/src, supply, then auditor --- confidential-transfer/proof-extraction/src/burn.rs | 8 ++++---- confidential-transfer/proof-extraction/src/mint.rs | 8 ++++---- confidential-transfer/proof-generation/src/burn.rs | 8 ++++---- .../proof-generation/src/encryption.rs | 8 ++++---- confidential-transfer/proof-generation/src/mint.rs | 10 +++++----- confidential-transfer/proof-tests/tests/proof_test.rs | 2 +- .../extension/confidential_mint_burn/account_info.rs | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/confidential-transfer/proof-extraction/src/burn.rs b/confidential-transfer/proof-extraction/src/burn.rs index dbfa6d1e8..daa02ebd5 100644 --- a/confidential-transfer/proof-extraction/src/burn.rs +++ b/confidential-transfer/proof-extraction/src/burn.rs @@ -12,8 +12,8 @@ use { /// The public keys associated with a confidential burn pub struct BurnPubkeys { pub source: PodElGamalPubkey, - pub auditor: PodElGamalPubkey, pub supply: PodElGamalPubkey, + pub auditor: PodElGamalPubkey, } /// The proof context information needed to process a confidential burn @@ -51,8 +51,8 @@ impl BurnProofContext { // `BurnProofContext`. let BatchedGroupedCiphertext3HandlesValidityProofContext { first_pubkey: source_elgamal_pubkey_from_validity_proof, - second_pubkey: auditor_elgamal_pubkey, - third_pubkey: supply_elgamal_pubkey, + second_pubkey: supply_elgamal_pubkey, + third_pubkey: auditor_elgamal_pubkey, grouped_ciphertext_lo: burn_amount_ciphertext_lo, grouped_ciphertext_hi: burn_amount_ciphertext_hi, } = ciphertext_validity_proof_context; @@ -116,8 +116,8 @@ impl BurnProofContext { let burn_pubkeys = BurnPubkeys { source: *source_elgamal_pubkey_from_equality_proof, - auditor: *auditor_elgamal_pubkey, supply: *supply_elgamal_pubkey, + auditor: *auditor_elgamal_pubkey, }; Ok(BurnProofContext { diff --git a/confidential-transfer/proof-extraction/src/mint.rs b/confidential-transfer/proof-extraction/src/mint.rs index 97f67f91a..c6191c2a9 100644 --- a/confidential-transfer/proof-extraction/src/mint.rs +++ b/confidential-transfer/proof-extraction/src/mint.rs @@ -12,8 +12,8 @@ use { /// The public keys associated with a confidential mint pub struct MintPubkeys { pub destination: PodElGamalPubkey, - pub auditor: PodElGamalPubkey, pub supply: PodElGamalPubkey, + pub auditor: PodElGamalPubkey, } /// The proof context information needed to process a confidential mint @@ -49,8 +49,8 @@ impl MintProofContext { // fields should be returned as part of `MintProofContext`. let BatchedGroupedCiphertext3HandlesValidityProofContext { first_pubkey: destination_elgamal_pubkey, - second_pubkey: auditor_elgamal_pubkey, - third_pubkey: supply_elgamal_pubkey_from_ciphertext_validity_proof, + second_pubkey: supply_elgamal_pubkey_from_ciphertext_validity_proof, + third_pubkey: auditor_elgamal_pubkey, grouped_ciphertext_lo: mint_amount_ciphertext_lo, grouped_ciphertext_hi: mint_amount_ciphertext_hi, } = ciphertext_validity_proof_context; @@ -116,8 +116,8 @@ impl MintProofContext { let mint_pubkeys = MintPubkeys { destination: *destination_elgamal_pubkey, - auditor: *auditor_elgamal_pubkey, supply: *supply_elgamal_pubkey_from_equality_proof, + auditor: *auditor_elgamal_pubkey, }; Ok(MintProofContext { diff --git a/confidential-transfer/proof-generation/src/burn.rs b/confidential-transfer/proof-generation/src/burn.rs index 7d7b788fb..35e88cd5b 100644 --- a/confidential-transfer/proof-generation/src/burn.rs +++ b/confidential-transfer/proof-generation/src/burn.rs @@ -36,8 +36,8 @@ pub fn burn_split_proof_data( burn_amount: u64, source_elgamal_keypair: &ElGamalKeypair, source_aes_key: &AeKey, - auditor_elgamal_pubkey: Option<&ElGamalPubkey>, supply_elgamal_pubkey: &ElGamalPubkey, + auditor_elgamal_pubkey: Option<&ElGamalPubkey>, ) -> Result { let default_auditor_pubkey = ElGamalPubkey::default(); let auditor_elgamal_pubkey = auditor_elgamal_pubkey.unwrap_or(&default_auditor_pubkey); @@ -50,15 +50,15 @@ pub fn burn_split_proof_data( let (burn_amount_ciphertext_lo, burn_amount_opening_lo) = BurnAmountCiphertext::new( burn_amount_lo, source_elgamal_keypair.pubkey(), - auditor_elgamal_pubkey, supply_elgamal_pubkey, + auditor_elgamal_pubkey, ); let (burn_amount_ciphertext_hi, burn_amount_opening_hi) = BurnAmountCiphertext::new( burn_amount_hi, source_elgamal_keypair.pubkey(), - auditor_elgamal_pubkey, supply_elgamal_pubkey, + auditor_elgamal_pubkey, ); // decrypt the current available balance at the source @@ -106,8 +106,8 @@ pub fn burn_split_proof_data( // generate ciphertext validity data let ciphertext_validity_proof_data = BatchedGroupedCiphertext3HandlesValidityProofData::new( source_elgamal_keypair.pubkey(), - auditor_elgamal_pubkey, supply_elgamal_pubkey, + auditor_elgamal_pubkey, &burn_amount_ciphertext_lo.0, &burn_amount_ciphertext_hi.0, burn_amount_lo, diff --git a/confidential-transfer/proof-generation/src/encryption.rs b/confidential-transfer/proof-generation/src/encryption.rs index 3f3f875aa..e15ae3f2d 100644 --- a/confidential-transfer/proof-generation/src/encryption.rs +++ b/confidential-transfer/proof-generation/src/encryption.rs @@ -95,12 +95,12 @@ impl BurnAmountCiphertext { pub fn new( amount: u64, source_pubkey: &ElGamalPubkey, - auditor_pubkey: &ElGamalPubkey, supply_pubkey: &ElGamalPubkey, + auditor_pubkey: &ElGamalPubkey, ) -> (Self, PedersenOpening) { let opening = PedersenOpening::new_rand(); let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with( - [source_pubkey, auditor_pubkey, supply_pubkey], + [source_pubkey, supply_pubkey, auditor_pubkey], amount, &opening, ); @@ -121,12 +121,12 @@ impl MintAmountCiphertext { pub fn new( amount: u64, source_pubkey: &ElGamalPubkey, - auditor_pubkey: &ElGamalPubkey, supply_pubkey: &ElGamalPubkey, + auditor_pubkey: &ElGamalPubkey, ) -> (Self, PedersenOpening) { let opening = PedersenOpening::new_rand(); let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with( - [source_pubkey, auditor_pubkey, supply_pubkey], + [source_pubkey, supply_pubkey, auditor_pubkey], amount, &opening, ); diff --git a/confidential-transfer/proof-generation/src/mint.rs b/confidential-transfer/proof-generation/src/mint.rs index 8e03e6d6c..50fd0cdd9 100644 --- a/confidential-transfer/proof-generation/src/mint.rs +++ b/confidential-transfer/proof-generation/src/mint.rs @@ -49,25 +49,25 @@ pub fn mint_split_proof_data( let (mint_amount_grouped_ciphertext_lo, mint_amount_opening_lo) = MintAmountCiphertext::new( mint_amount_lo, destination_elgamal_pubkey, - auditor_elgamal_pubkey, supply_elgamal_keypair.pubkey(), + auditor_elgamal_pubkey, ); let (mint_amount_grouped_ciphertext_hi, mint_amount_opening_hi) = MintAmountCiphertext::new( mint_amount_hi, destination_elgamal_pubkey, - auditor_elgamal_pubkey, supply_elgamal_keypair.pubkey(), + auditor_elgamal_pubkey, ); // compute the new supply ciphertext let mint_amount_ciphertext_supply_lo = mint_amount_grouped_ciphertext_lo .0 - .to_elgamal_ciphertext(2) + .to_elgamal_ciphertext(1) .unwrap(); let mint_amount_ciphertext_supply_hi = mint_amount_grouped_ciphertext_hi .0 - .to_elgamal_ciphertext(2) + .to_elgamal_ciphertext(1) .unwrap(); #[allow(clippy::arithmetic_side_effects)] @@ -99,8 +99,8 @@ pub fn mint_split_proof_data( // generate ciphertext validity proof data let ciphertext_validity_proof_data = BatchedGroupedCiphertext3HandlesValidityProofData::new( destination_elgamal_pubkey, - auditor_elgamal_pubkey, supply_elgamal_keypair.pubkey(), + auditor_elgamal_pubkey, &mint_amount_grouped_ciphertext_lo.0, &mint_amount_grouped_ciphertext_hi.0, mint_amount_lo, diff --git a/confidential-transfer/proof-tests/tests/proof_test.rs b/confidential-transfer/proof-tests/tests/proof_test.rs index b9444cd40..35749a539 100644 --- a/confidential-transfer/proof-tests/tests/proof_test.rs +++ b/confidential-transfer/proof-tests/tests/proof_test.rs @@ -288,8 +288,8 @@ fn test_burn_validity(spendable_balance: u64, burn_amount: u64) { burn_amount, &source_keypair, &aes_key, - Some(auditor_pubkey), supply_pubkey, + Some(auditor_pubkey), ) .unwrap(); diff --git a/program/src/extension/confidential_mint_burn/account_info.rs b/program/src/extension/confidential_mint_burn/account_info.rs index f0900333c..210f188bc 100644 --- a/program/src/extension/confidential_mint_burn/account_info.rs +++ b/program/src/extension/confidential_mint_burn/account_info.rs @@ -201,8 +201,8 @@ impl BurnAccountInfo { burn_amount, source_elgamal_keypair, aes_key, - auditor_elgamal_pubkey, supply_elgamal_pubkey, + auditor_elgamal_pubkey, ) .map_err(|e| -> TokenError { e.into() }) } From 0710d4a4dcf62dd57d21020763a418e5f090c927 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sat, 8 Feb 2025 10:31:46 +0900 Subject: [PATCH 2/3] add checks that the supply in the mint is updated correctly --- .../tests/confidential_mint_burn.rs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/clients/rust-legacy/tests/confidential_mint_burn.rs b/clients/rust-legacy/tests/confidential_mint_burn.rs index a4e33ad36..7caa5e9c0 100644 --- a/clients/rust-legacy/tests/confidential_mint_burn.rs +++ b/clients/rust-legacy/tests/confidential_mint_burn.rs @@ -1077,6 +1077,7 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) .await .unwrap(); + // check that the right amount is minted to the destination account let state = token .get_account_info(&alice_meta.token_account) .await @@ -1102,6 +1103,23 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) 0 ); + // check that the supply in the mint is updated correctly + let mint = token.get_mint_info().await.unwrap(); + let extension = mint.get_extension::().unwrap(); + assert_eq!( + supply_elgamal_keypair + .secret() + .decrypt_u32(&extension.confidential_supply.try_into().unwrap()) + .unwrap(), + mint_amount + ); // this test fails due to wrong supply ciphertexts being added + assert_eq!( + supply_aes_key + .decrypt(&extension.decryptable_supply.try_into().unwrap()) + .unwrap(), + mint_amount + ); + token .confidential_transfer_apply_pending_balance( &alice_meta.token_account, @@ -1129,6 +1147,7 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) .await .unwrap(); + // check that the right amount is burned in the source account let state = token .get_account_info(&alice_meta.token_account) .await @@ -1153,4 +1172,40 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) .unwrap(), 0 ); + + // check that the supply in the mint is updated correctly + let mint = token.get_mint_info().await.unwrap(); + let extension = mint.get_extension::().unwrap(); + assert_eq!( + supply_elgamal_keypair + .secret() + .decrypt_u32(&extension.confidential_supply.try_into().unwrap()) + .unwrap(), + 0 + ); // this test fails due to wrong supply ciphertexts being subtracted + assert_eq!( + supply_aes_key + .decrypt(&extension.decryptable_supply.try_into().unwrap()) + .unwrap(), + mint_amount, + ); + + let new_decryptable_supply = supply_aes_key.encrypt(0).into(); + token + .confidential_transfer_update_decrypt_supply( + &mint_authority.pubkey(), + &new_decryptable_supply, + &[&mint_authority], + ) + .await + .unwrap(); + + let mint = token.get_mint_info().await.unwrap(); + let extension = mint.get_extension::().unwrap(); + assert_eq!( + supply_aes_key + .decrypt(&extension.decryptable_supply.try_into().unwrap()) + .unwrap(), + 0, + ); } From ca023ca96dcc8a4f790c56f2f087fb346292147f Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sat, 8 Feb 2025 10:32:51 +0900 Subject: [PATCH 3/3] add and subtract the correct ciphertext to the encrypted supply --- clients/rust-legacy/tests/confidential_mint_burn.rs | 4 ++-- program/src/extension/confidential_mint_burn/processor.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/rust-legacy/tests/confidential_mint_burn.rs b/clients/rust-legacy/tests/confidential_mint_burn.rs index 7caa5e9c0..b9293c215 100644 --- a/clients/rust-legacy/tests/confidential_mint_burn.rs +++ b/clients/rust-legacy/tests/confidential_mint_burn.rs @@ -1112,7 +1112,7 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) .decrypt_u32(&extension.confidential_supply.try_into().unwrap()) .unwrap(), mint_amount - ); // this test fails due to wrong supply ciphertexts being added + ); assert_eq!( supply_aes_key .decrypt(&extension.decryptable_supply.try_into().unwrap()) @@ -1182,7 +1182,7 @@ async fn confidential_mint_burn_with_option(option: ConfidentialTransferOption) .decrypt_u32(&extension.confidential_supply.try_into().unwrap()) .unwrap(), 0 - ); // this test fails due to wrong supply ciphertexts being subtracted + ); assert_eq!( supply_aes_key .decrypt(&extension.decryptable_supply.try_into().unwrap()) diff --git a/program/src/extension/confidential_mint_burn/processor.rs b/program/src/extension/confidential_mint_burn/processor.rs index 1f63a7c47..d0911cd5d 100644 --- a/program/src/extension/confidential_mint_burn/processor.rs +++ b/program/src/extension/confidential_mint_burn/processor.rs @@ -260,11 +260,11 @@ fn process_confidential_mint( ¤t_supply, &proof_context .mint_amount_ciphertext_lo - .try_extract_ciphertext(2) + .try_extract_ciphertext(1) .map_err(|_| ProgramError::InvalidAccountData)?, &proof_context .mint_amount_ciphertext_hi - .try_extract_ciphertext(2) + .try_extract_ciphertext(1) .map_err(|_| ProgramError::InvalidAccountData)?, ) .ok_or(TokenError::CiphertextArithmeticFailed)?; @@ -395,11 +395,11 @@ fn process_confidential_burn( ¤t_supply, &proof_context .burn_amount_ciphertext_lo - .try_extract_ciphertext(2) + .try_extract_ciphertext(1) .map_err(|_| ProgramError::InvalidAccountData)?, &proof_context .burn_amount_ciphertext_hi - .try_extract_ciphertext(2) + .try_extract_ciphertext(1) .map_err(|_| ProgramError::InvalidAccountData)?, ) .ok_or(TokenError::CiphertextArithmeticFailed)?;