spl_token_confidential_transfer_proof_extraction/
withdraw.rs1use {
2 crate::errors::TokenProofExtractionError,
3 solana_zk_sdk::{
4 encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey},
5 zk_elgamal_proof_program::proof_data::{
6 BatchedRangeProofContext, CiphertextCommitmentEqualityProofContext,
7 },
8 },
9};
10
11const REMAINING_BALANCE_BIT_LENGTH: u8 = 64;
12
13pub struct WithdrawProofContext {
14 pub source_pubkey: PodElGamalPubkey,
15 pub remaining_balance_ciphertext: PodElGamalCiphertext,
16}
17
18impl WithdrawProofContext {
19 pub fn verify_and_extract(
20 equality_proof_context: &CiphertextCommitmentEqualityProofContext,
21 range_proof_context: &BatchedRangeProofContext,
22 ) -> Result<Self, TokenProofExtractionError> {
23 let CiphertextCommitmentEqualityProofContext {
24 pubkey: source_pubkey,
25 ciphertext: remaining_balance_ciphertext,
26 commitment: remaining_balance_commitment,
27 } = equality_proof_context;
28
29 let BatchedRangeProofContext {
30 commitments: range_proof_commitments,
31 bit_lengths: range_proof_bit_lengths,
32 } = range_proof_context;
33
34 if range_proof_commitments[0] != *remaining_balance_commitment {
37 return Err(TokenProofExtractionError::PedersenCommitmentMismatch);
38 }
39
40 if range_proof_bit_lengths[0] != REMAINING_BALANCE_BIT_LENGTH {
43 return Err(TokenProofExtractionError::RangeProofLengthMismatch);
44 }
45
46 let context_info = WithdrawProofContext {
47 source_pubkey: *source_pubkey,
48 remaining_balance_ciphertext: *remaining_balance_ciphertext,
49 };
50
51 Ok(context_info)
52 }
53}