Skip to content

Commit

Permalink
review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
abcalphabet committed Oct 7, 2024
1 parent 32e06db commit 4fea36d
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 210 deletions.
1 change: 0 additions & 1 deletion token/confidential-transfer/proof-generation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ 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
31 changes: 2 additions & 29 deletions token/confidential-transfer/proof-generation/src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ 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 @@ -33,8 +32,8 @@ pub struct MintProofData {

pub fn mint_split_proof_data(
current_supply_ciphertext: &ElGamalCiphertext,
current_decryptable_supply: &AeCiphertext,
mint_amount: u64,
current_supply: u64,
supply_elgamal_keypair: &ElGamalKeypair,
supply_aes_key: &AeKey,
destination_elgamal_pubkey: &ElGamalPubkey,
Expand Down Expand Up @@ -79,34 +78,8 @@ pub fn mint_split_proof_data(
)
.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;
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_decyptable_supply
.checked_sub(decryptable_to_current_diff)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?
let new_supply = current_supply
.checked_add(mint_amount)
.ok_or(TokenProofGenerationError::IllegalAmountBitLength)?;

Expand Down
31 changes: 0 additions & 31 deletions token/confidential-transfer/proof-generation/src/supply.rs

This file was deleted.

3 changes: 1 addition & 2 deletions token/confidential-transfer/proof-tests/tests/proof_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ fn test_mint_validity(mint_amount: u64, supply: u64) {
let supply_aes_key = AeKey::new_rand();

let supply_ciphertext = supply_keypair.pubkey().encrypt(supply);
let decryptable_supply = supply_aes_key.encrypt(supply);

let MintProofData {
equality_proof_data,
Expand All @@ -226,8 +225,8 @@ fn test_mint_validity(mint_amount: u64, supply: u64) {
new_decryptable_supply: _,
} = mint_split_proof_data(
&supply_ciphertext,
&decryptable_supply,
mint_amount,
supply,
&supply_keypair,
&supply_aes_key,
destination_pubkey,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use {
super::ConfidentialMintBurn,
crate::error::TokenError,
bytemuck::{Pod, Zeroable},
solana_zk_sdk::{
encryption::{
auth_encryption::{AeCiphertext, AeKey},
elgamal::{ElGamalCiphertext, ElGamalKeypair},
pedersen::PedersenOpening,
pod::{auth_encryption::PodAeCiphertext, elgamal::PodElGamalCiphertext},
},
zk_elgamal_proof_program::proof_data::CiphertextCiphertextEqualityProofData,
},
spl_pod::optional_keys::OptionalNonZeroElGamalPubkey,
};

/// Confidential Mint Burn extension information needed to construct a
/// `RotateSupplyElgamalPubkey` instruction.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
pub struct SupplyAccountInfo {
/// The available balance (encrypted by `encrypiton_pubkey`)
pub current_supply: PodElGamalCiphertext,
/// The decryptable supply
pub decryptable_supply: PodAeCiphertext,
/// The supply's elgamal pubkey
pub supply_elgamal_pubkey: OptionalNonZeroElGamalPubkey,
}

impl SupplyAccountInfo {
/// Creates a SupplyAccountInfo from ConfidentialMintBurn extension account
/// data
pub fn new(extension: ConfidentialMintBurn) -> Self {
Self {
current_supply: extension.confidential_supply,
decryptable_supply: extension.decryptable_supply,
supply_elgamal_pubkey: extension.supply_elgamal_pubkey,
}
}

/// Computes the current supply from the decryptable supply and the
/// difference between the decryptable supply and the elgamal encrypted
/// supply ciphertext
pub fn decrypt_current_supply(
&self,
aes_key: &AeKey,
elgamal_keypair: &ElGamalKeypair,
) -> Result<u64, TokenError> {
if self.supply_elgamal_pubkey.is_none() {
return Err(TokenError::InvalidState);
}
// fresh mints are initialized with a zeroed decryptable_supply
// TODO: include decryptable supply in InitMint instruction
let current_decyptable_supply = if self.decryptable_supply != PodAeCiphertext::default() {
// decrypt the current supply
TryInto::<AeCiphertext>::try_into(self.decryptable_supply)
.map_err(|_| TokenError::MalformedCiphertext)?
.decrypt(aes_key)
.ok_or(TokenError::MalformedCiphertext)?
} 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 =
elgamal_keypair.pubkey().encrypt(current_decyptable_supply);
#[allow(clippy::arithmetic_side_effects)]
let supply_delta_ciphertext = decryptable_supply_ciphertext
- (TryInto::<ElGamalCiphertext>::try_into(self.current_supply)
.map_err(|_| TokenError::MalformedCiphertext)?);
let decryptable_to_current_diff = elgamal_keypair
.secret()
.decrypt_u32(&supply_delta_ciphertext)
.ok_or(TokenError::MalformedCiphertext)?;

// compute the current supply
current_decyptable_supply
.checked_sub(decryptable_to_current_diff)
.ok_or(TokenError::Overflow)
}

/// Generates the `CiphertextCiphertextEqualityProofData` needed for a
/// `RotateSupplyElgamalPubkey` instruction
pub fn generate_rotate_supply_elgamal_pubkey_proof(
&self,
aes_key: &AeKey,
current_supply_elgamal_keypair: &ElGamalKeypair,
new_supply_elgamal_keypair: &ElGamalKeypair,
) -> Result<CiphertextCiphertextEqualityProofData, TokenError> {
let current_supply =
self.decrypt_current_supply(aes_key, current_supply_elgamal_keypair)?;

let new_supply_opening = PedersenOpening::new_rand();
let new_supply_ciphertext = new_supply_elgamal_keypair
.pubkey()
.encrypt_with(current_supply, &new_supply_opening);

CiphertextCiphertextEqualityProofData::new(
current_supply_elgamal_keypair,
new_supply_elgamal_keypair.pubkey(),
&self
.current_supply
.try_into()
.map_err(|_| TokenError::MalformedCiphertext)?,
&new_supply_ciphertext,
&new_supply_opening,
current_supply,
)
.map_err(|_| TokenError::ProofGeneration)
}
}
Loading

0 comments on commit 4fea36d

Please sign in to comment.