Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confidential mint burn extension: Token program changes #7319

Merged
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8fbb0fb
confidential mint-burn extension
abcalphabet Jun 19, 2024
de3d227
Merge branch 'master' into confidential_mint_burn_ext
abcalphabet Jul 1, 2024
32d528e
add ciphertext validity proof to confidential mint
abcalphabet Jul 1, 2024
3a9318d
simplify burn proofs
abcalphabet Jul 2, 2024
fee8acb
add confidential supply
abcalphabet Jul 5, 2024
5bbafec
remove debug statements
abcalphabet Jul 5, 2024
d6724a0
add tests for confidential mint-burn
abcalphabet Jul 5, 2024
0ec8537
Merge branch 'master' into confidential_mint_burn_ext
abcalphabet Jul 10, 2024
5939b72
fix clippy & serde tests
abcalphabet Jul 11, 2024
d4ad146
Merge branch 'master' into confidential_mint_burn_ext
abcalphabet Sep 4, 2024
8479bad
fix some tests
abcalphabet Sep 4, 2024
96d8f92
Merge branch 'master' into confidential_mint_burn_ext
abcalphabet Sep 4, 2024
0b20da3
clippy
abcalphabet Sep 4, 2024
48fcb02
Merge branch 'master' into confidential_mint_burn_ext
abcalphabet Sep 25, 2024
18aa58d
mint burn with new proof generation
abcalphabet Oct 1, 2024
59234ba
remove old mintburn proof generation
abcalphabet Oct 1, 2024
89c7cd2
cleanup
abcalphabet Oct 1, 2024
d46407c
remove cli / client changes and mint-burn tests
abcalphabet Oct 1, 2024
3944195
cleanup
abcalphabet Oct 1, 2024
e010003
more cleanup
abcalphabet Oct 1, 2024
42e0193
fix clippy; serde logic
abcalphabet Oct 2, 2024
e0aefa2
Update token/program-2022/src/extension/confidential_mint_burn/mod.rs
abcalphabet Oct 4, 2024
f795a3f
Update token/program-2022/src/extension/confidential_mint_burn/instru…
abcalphabet Oct 4, 2024
c2ec29a
review fixes
abcalphabet Oct 4, 2024
2a1316f
refactor proof location processing
abcalphabet Oct 4, 2024
3908688
comment
abcalphabet Oct 4, 2024
57684cf
cleanup
abcalphabet Oct 4, 2024
32e06db
fix target_os=solana ; test-sbf
abcalphabet Oct 5, 2024
4fea36d
review fixes
abcalphabet Oct 7, 2024
3a14e2e
fix fmt / serde
abcalphabet Oct 8, 2024
8ad746e
construct supply account info from ref to extension
abcalphabet Oct 8, 2024
df6cd8b
add conf mint/burn failure docs; remove todo
abcalphabet Oct 9, 2024
20c84b5
remove obsolete null check
abcalphabet Oct 9, 2024
bcc0812
Update token/program-2022/src/error.rs
abcalphabet Oct 24, 2024
1d2b804
Update token/program-2022/src/extension/confidential_mint_burn/instru…
abcalphabet Oct 24, 2024
534861e
Update token/program-2022/src/extension/confidential_mint_burn/accoun…
abcalphabet Oct 24, 2024
b01ac24
review fixes
abcalphabet Oct 24, 2024
f601fdd
Merge branch 'master' into confidential_mint_burn_ext_program
abcalphabet Oct 25, 2024
5256e9d
more fixes
abcalphabet Oct 28, 2024
3f3c66e
Merge branch 'master' into confidential_mint_burn_ext_program
abcalphabet Oct 28, 2024
fbff190
clippy; review fixes
abcalphabet Oct 29, 2024
d46193f
Merge branch 'master' into confidential_mint_burn_ext_program
abcalphabet Oct 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libraries/pod/src/optional_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ impl From<OptionalNonZeroElGamalPubkey> for Option<PodElGamalPubkey> {
}
}
}
impl OptionalNonZeroElGamalPubkey {
pub fn is_none(&self) -> bool {
self.0 == PodElGamalPubkey::default()
}
pub fn is_some(&self) -> bool {
self.0 != PodElGamalPubkey::default()
}
}
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(feature = "serde-traits")]
impl Serialize for OptionalNonZeroElGamalPubkey {
Expand Down
9 changes: 8 additions & 1 deletion token/cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ use {
},
spl_token_group_interface::state::TokenGroup,
spl_token_metadata_interface::state::{Field, TokenMetadata},
std::{collections::HashMap, fmt::Display, process::exit, rc::Rc, str::FromStr, sync::Arc},
std::{
collections::HashMap,
fmt::Display,
process::exit,
rc::Rc,
str::{self, FromStr},
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
sync::Arc,
},
};

fn print_error_and_exit<T, E: Display>(e: E) -> T {
Expand Down
4 changes: 2 additions & 2 deletions token/client/src/token.rs
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use {
ApplyPendingBalanceAccountInfo, EmptyAccountAccountInfo, TransferAccountInfo,
WithdrawAccountInfo,
},
instruction::{ProofContextState, ZkProofData},
ConfidentialTransferAccount, DecryptableBalance,
},
confidential_transfer_fee::{
Expand All @@ -57,8 +58,6 @@ use {
zk_elgamal_proof_program::{
self,
instruction::{close_context_state, ContextStateInfo},
proof_data::*,
state::ProofContextState,
},
},
state::{Account, AccountState, Mint, Multisig},
Expand Down Expand Up @@ -111,6 +110,7 @@ pub enum TokenError {
#[error("decimals specified, but incorrect")]
InvalidDecimals,
}

impl PartialEq for TokenError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
Expand Down
30 changes: 30 additions & 0 deletions token/confidential-transfer/proof-extraction/src/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,36 @@ impl PodFeeCiphertext {
#[repr(C)]
pub struct PodBurnAmountCiphertext(pub(crate) PodGroupedElGamalCiphertext3Handles);

impl PodBurnAmountCiphertext {
pub fn extract_commitment(&self) -> PodPedersenCommitment {
self.0.extract_commitment()
}
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved

pub fn try_extract_ciphertext(
&self,
index: usize,
) -> Result<PodElGamalCiphertext, TokenProofExtractionError> {
self.0
.try_extract_ciphertext(index)
.map_err(|_| TokenProofExtractionError::CiphertextExtraction)
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(C)]
pub struct PodMintAmountCiphertext(pub(crate) PodGroupedElGamalCiphertext3Handles);

impl PodMintAmountCiphertext {
pub fn extract_commitment(&self) -> PodPedersenCommitment {
self.0.extract_commitment()
}
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved

pub fn try_extract_ciphertext(
&self,
index: usize,
) -> Result<PodElGamalCiphertext, TokenProofExtractionError> {
self.0
.try_extract_ciphertext(index)
.map_err(|_| TokenProofExtractionError::CiphertextExtraction)
}
}
2 changes: 2 additions & 0 deletions token/confidential-transfer/proof-generation/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ pub enum TokenProofGenerationError {
IllegalAmountBitLength,
#[error("fee calculation failed")]
FeeCalculation,
#[error("supply decryption failed")]
SupplyDecryption,
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions token/confidential-transfer/proof-generation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod burn;
pub mod encryption;
pub mod errors;
pub mod mint;
pub mod supply;
pub mod transfer;
pub mod transfer_with_fee;
pub mod withdraw;
Expand Down
34 changes: 29 additions & 5 deletions token/confidential-transfer/proof-generation/src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use {
auth_encryption::{AeCiphertext, AeKey},
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey},
pedersen::Pedersen,
pod::auth_encryption::PodAeCiphertext,
},
zk_elgamal_proof_program::proof_data::{
BatchedGroupedCiphertext3HandlesValidityProofData, BatchedRangeProofU128Data,
Expand All @@ -27,6 +28,7 @@ pub struct MintProofData {
pub equality_proof_data: CiphertextCommitmentEqualityProofData,
pub ciphertext_validity_proof_data: BatchedGroupedCiphertext3HandlesValidityProofData,
pub range_proof_data: BatchedRangeProofU128Data,
pub new_decryptable_supply: AeCiphertext,
}

pub fn mint_split_proof_data(
Expand Down Expand Up @@ -77,13 +79,34 @@ pub fn mint_split_proof_data(
)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;

// decrypt the current supply
let current_supply = current_decryptable_supply
.decrypt(supply_aes_key)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;
// fresh mints are initialized with a zeroed decryptable_supply
// TODO: don't clone here once AeCiphertext implement Copy in the zk-sdk
let pod_decryptable_supply: PodAeCiphertext = current_decryptable_supply.clone().into();
let current_decyptable_supply = if pod_decryptable_supply != PodAeCiphertext::default() {
// decrypt the current supply
current_decryptable_supply
.decrypt(supply_aes_key)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?
} else {
0
};

// get the difference between the supply ciphertext and the decryptable supply
// explanation see https://github.com/solana-labs/solana-program-library/pull/6881#issuecomment-2385579058
let decryptable_supply_ciphertext = supply_elgamal_keypair
.pubkey()
.encrypt(current_decyptable_supply);
#[allow(clippy::arithmetic_side_effects)]
let ct_decryptable_to_current_diff = decryptable_supply_ciphertext - current_supply_ciphertext;
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
let decryptable_to_current_diff = supply_elgamal_keypair
.secret()
.decrypt_u32(&ct_decryptable_to_current_diff)
.ok_or(TokenProofGenerationError::SupplyDecryption)?;

// compute the new supply
let new_supply = current_supply
let new_supply = current_decyptable_supply
.checked_sub(decryptable_to_current_diff)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?
.checked_add(mint_amount)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;

Expand Down Expand Up @@ -142,5 +165,6 @@ pub fn mint_split_proof_data(
equality_proof_data,
ciphertext_validity_proof_data,
range_proof_data,
new_decryptable_supply: supply_aes_key.encrypt(new_supply),
})
}
31 changes: 31 additions & 0 deletions token/confidential-transfer/proof-generation/src/supply.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use {
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
crate::errors::TokenProofGenerationError,
solana_zk_sdk::{
encryption::{
elgamal::{ElGamalCiphertext, ElGamalKeypair},
pedersen::PedersenOpening,
},
zk_elgamal_proof_program::proof_data::CiphertextCiphertextEqualityProofData,
},
};

pub fn supply_elgamal_pubkey_rotation_proof(
current_supply: u64,
supply_elgamal_keypair: &ElGamalKeypair,
new_supply_elgamal_keypair: &ElGamalKeypair,
current_supply_ciphertext: ElGamalCiphertext,
) -> Result<CiphertextCiphertextEqualityProofData, TokenProofGenerationError> {
let new_supply_opening = PedersenOpening::new_rand();
let new_supply_ciphertext = new_supply_elgamal_keypair
.pubkey()
.encrypt_with(current_supply, &new_supply_opening);

Ok(CiphertextCiphertextEqualityProofData::new(
supply_elgamal_keypair,
new_supply_elgamal_keypair.pubkey(),
&current_supply_ciphertext,
&new_supply_ciphertext,
&new_supply_opening,
current_supply,
)?)
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ fn test_mint_validity(mint_amount: u64, supply: u64) {
equality_proof_data,
ciphertext_validity_proof_data,
range_proof_data,
new_decryptable_supply: _,
} = mint_split_proof_data(
&supply_ciphertext,
&decryptable_supply,
Expand Down
15 changes: 15 additions & 0 deletions token/program-2022/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@ pub enum TokenError {
/// Fee calculation failed
#[error("Fee calculation failed")]
FeeCalculation,

//65
/// Withdraw / Deposit not allowed for confidential-mint-burn
#[error("When the confidential-mint-burn extension is enabled, mints are only allowed into the confidential balance. Likewise conversions confidential token balance to normal balance and vice versa are illegal.")]
IllegalMintBurnConversion,
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
/// Undecryptable supply when trying to generate confidential-mint proofs
#[error("Could not decrypt difference between current supply and decryptable supply when generating mint proofs")]
SupplyDecryption,
abcalphabet marked this conversation as resolved.
Show resolved Hide resolved
}
impl From<TokenError> for ProgramError {
fn from(e: TokenError) -> Self {
Expand Down Expand Up @@ -445,6 +453,12 @@ impl PrintProgramError for TokenError {
TokenError::FeeCalculation => {
msg!("Transfer fee calculation failed")
}
TokenError::IllegalMintBurnConversion => {
msg!("Conversions from normal to confidential token balance and vice versa are illegal if the confidential-mint-burn extension is enabled")
}
TokenError::SupplyDecryption => {
msg!("Could not decrypt difference between current supply and decryptable supply when generating mint proofs")
}
}
}
}
Expand All @@ -457,6 +471,7 @@ impl From<TokenProofGenerationError> for TokenError {
TokenProofGenerationError::NotEnoughFunds => TokenError::InsufficientFunds,
TokenProofGenerationError::IllegalAmountBitLength => TokenError::IllegalBitLength,
TokenProofGenerationError::FeeCalculation => TokenError::FeeCalculation,
TokenProofGenerationError::SupplyDecryption => TokenError::SupplyDecryption,
}
}
}
Expand Down
Loading
Loading