forked from solana-labs/solana-program-library
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[confidential-transfer] Add withdraw proof generation and extraction (s…
…olana-labs#6954) * add withdraw proof generation * add withdraw proof extraction * re-organize proof data using structs
- Loading branch information
1 parent
8885d7c
commit 31931a7
Showing
5 changed files
with
157 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ pub mod encryption; | |
pub mod errors; | ||
pub mod transfer; | ||
pub mod transfer_with_fee; | ||
pub mod withdraw; |
53 changes: 53 additions & 0 deletions
53
token/confidential-transfer/proof-extraction/src/withdraw.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use { | ||
crate::errors::TokenProofExtractionError, | ||
solana_zk_sdk::{ | ||
encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, | ||
zk_elgamal_proof_program::proof_data::{ | ||
BatchedRangeProofContext, CiphertextCommitmentEqualityProofContext, | ||
}, | ||
}, | ||
}; | ||
|
||
const REMAINING_BALANCE_BIT_LENGTH: u8 = 64; | ||
|
||
pub struct WithdrawProofContext { | ||
pub source_pubkey: PodElGamalPubkey, | ||
pub remaining_balance_ciphertext: PodElGamalCiphertext, | ||
} | ||
|
||
impl WithdrawProofContext { | ||
pub fn verify_and_extract( | ||
equality_proof_context: &CiphertextCommitmentEqualityProofContext, | ||
range_proof_context: &BatchedRangeProofContext, | ||
) -> Result<Self, TokenProofExtractionError> { | ||
let CiphertextCommitmentEqualityProofContext { | ||
pubkey: source_pubkey, | ||
ciphertext: remaining_balance_ciphertext, | ||
commitment: remaining_balance_commitment, | ||
} = equality_proof_context; | ||
|
||
let BatchedRangeProofContext { | ||
commitments: range_proof_commitments, | ||
bit_lengths: range_proof_bit_lengths, | ||
} = range_proof_context; | ||
|
||
if range_proof_commitments.is_empty() | ||
|| range_proof_commitments[0] != *remaining_balance_commitment | ||
{ | ||
return Err(TokenProofExtractionError::PedersenCommitmentMismatch); | ||
} | ||
|
||
if range_proof_bit_lengths.is_empty() | ||
|| range_proof_bit_lengths[0] != REMAINING_BALANCE_BIT_LENGTH | ||
{ | ||
return Err(TokenProofExtractionError::RangeProofLengthMismatch); | ||
} | ||
|
||
let context_info = WithdrawProofContext { | ||
source_pubkey: *source_pubkey, | ||
remaining_balance_ciphertext: *remaining_balance_ciphertext, | ||
}; | ||
|
||
Ok(context_info) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
token/confidential-transfer/proof-generation/src/withdraw.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use { | ||
crate::errors::TokenProofGenerationError, | ||
solana_zk_sdk::{ | ||
encryption::{ | ||
elgamal::{ElGamal, ElGamalCiphertext, ElGamalKeypair}, | ||
pedersen::Pedersen, | ||
}, | ||
zk_elgamal_proof_program::proof_data::{ | ||
BatchedRangeProofU64Data, CiphertextCommitmentEqualityProofData, | ||
}, | ||
}, | ||
}; | ||
|
||
const REMAINING_BALANCE_BIT_LENGTH: usize = 64; | ||
|
||
/// Proof data required for a withdraw instruction | ||
pub struct WithdrawProofData { | ||
pub equality_proof_data: CiphertextCommitmentEqualityProofData, | ||
pub range_proof_data: BatchedRangeProofU64Data, | ||
} | ||
|
||
pub fn withdraw_proof_data( | ||
current_available_balance: &ElGamalCiphertext, | ||
current_balance: u64, | ||
withdraw_amount: u64, | ||
elgamal_keypair: &ElGamalKeypair, | ||
) -> Result<WithdrawProofData, TokenProofGenerationError> { | ||
// Calculate the remaining balance after withdraw | ||
let remaining_balance = current_balance | ||
.checked_sub(withdraw_amount) | ||
.ok_or(TokenProofGenerationError::NotEnoughFunds)?; | ||
|
||
// Generate a Pedersen commitment for the remaining balance | ||
let (remaining_balance_commitment, remaining_balance_opening) = | ||
Pedersen::new(remaining_balance); | ||
|
||
// Compute the remaining balance ciphertext | ||
#[allow(clippy::arithmetic_side_effects)] | ||
let remaining_balance_ciphertext = current_available_balance - ElGamal::encode(withdraw_amount); | ||
|
||
// Generate proof data | ||
let equality_proof_data = CiphertextCommitmentEqualityProofData::new( | ||
elgamal_keypair, | ||
&remaining_balance_ciphertext, | ||
&remaining_balance_commitment, | ||
&remaining_balance_opening, | ||
remaining_balance, | ||
) | ||
.map_err(TokenProofGenerationError::from)?; | ||
|
||
let range_proof_data = BatchedRangeProofU64Data::new( | ||
vec![&remaining_balance_commitment], | ||
vec![remaining_balance], | ||
vec![REMAINING_BALANCE_BIT_LENGTH], | ||
vec![&remaining_balance_opening], | ||
) | ||
.map_err(TokenProofGenerationError::from)?; | ||
|
||
Ok(WithdrawProofData { | ||
equality_proof_data, | ||
range_proof_data, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters