5151 encryption:: {
5252 auth_encryption:: AeKey ,
5353 elgamal:: { ElGamalCiphertext , ElGamalKeypair , ElGamalPubkey , ElGamalSecretKey } ,
54- pod:: elgamal:: PodElGamalPubkey ,
54+ pod:: elgamal:: { PodElGamalCiphertext , PodElGamalPubkey } ,
5555 } ,
5656 zk_elgamal_proof_program:: {
5757 self ,
@@ -348,6 +348,12 @@ pub enum ProofAccount {
348348 RecordAccount ( Pubkey , u32 ) ,
349349}
350350
351+ pub struct ProofAccountWithCiphertext {
352+ pub proof_account : ProofAccount ,
353+ pub ciphertext_lo : PodElGamalCiphertext ,
354+ pub ciphertext_hi : PodElGamalCiphertext ,
355+ }
356+
351357pub struct Token < T > {
352358 client : Arc < dyn ProgramClient < T > > ,
353359 pubkey : Pubkey , /* token mint */
@@ -2198,7 +2204,7 @@ where
21982204 destination_account : & Pubkey ,
21992205 source_authority : & Pubkey ,
22002206 equality_proof_account : Option < & ProofAccount > ,
2201- ciphertext_validity_proof_account : Option < & ProofAccount > ,
2207+ ciphertext_validity_proof_account_with_ciphertext : Option < & ProofAccountWithCiphertext > ,
22022208 range_proof_account : Option < & ProofAccount > ,
22032209 transfer_amount : u64 ,
22042210 account_info : Option < TransferAccountInfo > ,
@@ -2220,46 +2226,65 @@ where
22202226 TransferAccountInfo :: new ( confidential_transfer_account)
22212227 } ;
22222228
2223- let ( equality_proof_data, ciphertext_validity_proof_data, range_proof_data) = if [
2224- equality_proof_account,
2225- ciphertext_validity_proof_account,
2226- range_proof_account,
2227- ]
2228- . iter ( )
2229- . all ( |proof_account| proof_account. is_some ( ) )
2230- {
2231- ( None , None , None )
2232- } else {
2233- let TransferProofData {
2234- equality_proof_data,
2235- ciphertext_validity_proof_data,
2236- range_proof_data,
2237- } = account_info
2238- . generate_split_transfer_proof_data (
2239- transfer_amount,
2240- source_elgamal_keypair,
2241- source_aes_key,
2242- destination_elgamal_pubkey,
2243- auditor_elgamal_pubkey,
2244- )
2245- . map_err ( |_| TokenError :: ProofGeneration ) ?;
2229+ let ( equality_proof_data, ciphertext_validity_proof_data_with_ciphertext, range_proof_data) =
2230+ if equality_proof_account. is_some ( )
2231+ && ciphertext_validity_proof_account_with_ciphertext. is_some ( )
2232+ && range_proof_account. is_some ( )
2233+ {
2234+ ( None , None , None )
2235+ } else {
2236+ let TransferProofData {
2237+ equality_proof_data,
2238+ ciphertext_validity_proof_data_with_ciphertext,
2239+ range_proof_data,
2240+ } = account_info
2241+ . generate_split_transfer_proof_data (
2242+ transfer_amount,
2243+ source_elgamal_keypair,
2244+ source_aes_key,
2245+ destination_elgamal_pubkey,
2246+ auditor_elgamal_pubkey,
2247+ )
2248+ . map_err ( |_| TokenError :: ProofGeneration ) ?;
22462249
2247- // if proof accounts are none, then proof data must be included as instruction
2248- // data
2249- let equality_proof_data = equality_proof_account
2250- . is_none ( )
2251- . then_some ( equality_proof_data) ;
2252- let ciphertext_validity_proof_data = ciphertext_validity_proof_account
2253- . is_none ( )
2254- . then_some ( ciphertext_validity_proof_data) ;
2255- let range_proof_data = range_proof_account. is_none ( ) . then_some ( range_proof_data) ;
2250+ // if proof accounts are none, then proof data must be included as instruction
2251+ // data
2252+ let equality_proof_data = equality_proof_account
2253+ . is_none ( )
2254+ . then_some ( equality_proof_data) ;
2255+ let ciphertext_validity_proof_data_with_ciphertext =
2256+ ciphertext_validity_proof_account_with_ciphertext
2257+ . is_none ( )
2258+ . then_some ( ciphertext_validity_proof_data_with_ciphertext) ;
2259+ let range_proof_data = range_proof_account. is_none ( ) . then_some ( range_proof_data) ;
22562260
2257- (
2258- equality_proof_data,
2259- ciphertext_validity_proof_data,
2260- range_proof_data,
2261- )
2262- } ;
2261+ (
2262+ equality_proof_data,
2263+ ciphertext_validity_proof_data_with_ciphertext,
2264+ range_proof_data,
2265+ )
2266+ } ;
2267+
2268+ let ( transfer_amount_auditor_ciphertext_lo, transfer_amount_auditor_ciphertext_hi) =
2269+ if let Some ( proof_data_with_ciphertext) = ciphertext_validity_proof_data_with_ciphertext
2270+ {
2271+ (
2272+ proof_data_with_ciphertext. ciphertext_lo ,
2273+ proof_data_with_ciphertext. ciphertext_hi ,
2274+ )
2275+ } else {
2276+ // unwrap is safe as long as either `proof_data_with_ciphertext`,
2277+ // `proof_account_with_ciphertext` is `Some(..)`, which is guaranteed by the
2278+ // previous check
2279+ (
2280+ ciphertext_validity_proof_account_with_ciphertext
2281+ . unwrap ( )
2282+ . ciphertext_lo ,
2283+ ciphertext_validity_proof_account_with_ciphertext
2284+ . unwrap ( )
2285+ . ciphertext_hi ,
2286+ )
2287+ } ;
22632288
22642289 // cannot panic as long as either `proof_data` or `proof_account` is `Some(..)`,
22652290 // which is guaranteed by the previous check
@@ -2269,9 +2294,11 @@ where
22692294 1 ,
22702295 )
22712296 . unwrap ( ) ;
2297+ let ciphertext_validity_proof_data =
2298+ ciphertext_validity_proof_data_with_ciphertext. map ( |data| data. proof_data ) ;
22722299 let ciphertext_validity_proof_location = Self :: confidential_transfer_create_proof_location (
22732300 ciphertext_validity_proof_data. as_ref ( ) ,
2274- ciphertext_validity_proof_account ,
2301+ ciphertext_validity_proof_account_with_ciphertext . map ( |account| & account . proof_account ) ,
22752302 2 ,
22762303 )
22772304 . unwrap ( ) ;
@@ -2292,6 +2319,8 @@ where
22922319 self . get_address ( ) ,
22932320 destination_account,
22942321 new_decryptable_available_balance. into ( ) ,
2322+ & transfer_amount_auditor_ciphertext_lo,
2323+ & transfer_amount_auditor_ciphertext_hi,
22952324 source_authority,
22962325 & multisig_signers,
22972326 equality_proof_location,
@@ -2526,7 +2555,9 @@ where
25262555 destination_account : & Pubkey ,
25272556 source_authority : & Pubkey ,
25282557 equality_proof_account : Option < & ProofAccount > ,
2529- transfer_amount_ciphertext_validity_proof_account : Option < & ProofAccount > ,
2558+ transfer_amount_ciphertext_validity_proof_account_with_ciphertext : Option <
2559+ & ProofAccountWithCiphertext ,
2560+ > ,
25302561 percentage_with_cap_proof_account : Option < & ProofAccount > ,
25312562 fee_ciphertext_validity_proof_account : Option < & ProofAccount > ,
25322563 range_proof_account : Option < & ProofAccount > ,
@@ -2555,26 +2586,22 @@ where
25552586
25562587 let (
25572588 equality_proof_data,
2558- transfer_amount_ciphertext_validity_proof_data ,
2589+ transfer_amount_ciphertext_validity_proof_data_with_ciphertext ,
25592590 percentage_with_cap_proof_data,
25602591 fee_ciphertext_validity_proof_data,
25612592 range_proof_data,
2562- ) = if [
2563- equality_proof_account,
2564- transfer_amount_ciphertext_validity_proof_account,
2565- percentage_with_cap_proof_account,
2566- fee_ciphertext_validity_proof_account,
2567- range_proof_account,
2568- ]
2569- . iter ( )
2570- . all ( |proof_account| proof_account. is_some ( ) )
2593+ ) = if equality_proof_account. is_some ( )
2594+ && transfer_amount_ciphertext_validity_proof_account_with_ciphertext. is_some ( )
2595+ && percentage_with_cap_proof_account. is_some ( )
2596+ && fee_ciphertext_validity_proof_account. is_some ( )
2597+ && range_proof_account. is_some ( )
25712598 {
25722599 // is all proofs come from accounts, then skip proof generation
25732600 ( None , None , None , None , None )
25742601 } else {
25752602 let TransferWithFeeProofData {
25762603 equality_proof_data,
2577- transfer_amount_ciphertext_validity_proof_data ,
2604+ transfer_amount_ciphertext_validity_proof_data_with_ciphertext ,
25782605 percentage_with_cap_proof_data,
25792606 fee_ciphertext_validity_proof_data,
25802607 range_proof_data,
@@ -2594,10 +2621,10 @@ where
25942621 let equality_proof_data = equality_proof_account
25952622 . is_none ( )
25962623 . then_some ( equality_proof_data) ;
2597- let transfer_amount_ciphertext_validity_proof_data =
2598- transfer_amount_ciphertext_validity_proof_account
2624+ let transfer_amount_ciphertext_validity_proof_data_with_ciphertext =
2625+ transfer_amount_ciphertext_validity_proof_account_with_ciphertext
25992626 . is_none ( )
2600- . then_some ( transfer_amount_ciphertext_validity_proof_data ) ;
2627+ . then_some ( transfer_amount_ciphertext_validity_proof_data_with_ciphertext ) ;
26012628 let percentage_with_cap_proof_data = percentage_with_cap_proof_account
26022629 . is_none ( )
26032630 . then_some ( percentage_with_cap_proof_data) ;
@@ -2608,13 +2635,35 @@ where
26082635
26092636 (
26102637 equality_proof_data,
2611- transfer_amount_ciphertext_validity_proof_data ,
2638+ transfer_amount_ciphertext_validity_proof_data_with_ciphertext ,
26122639 percentage_with_cap_proof_data,
26132640 fee_ciphertext_validity_proof_data,
26142641 range_proof_data,
26152642 )
26162643 } ;
26172644
2645+ let ( transfer_amount_auditor_ciphertext_lo, transfer_amount_auditor_ciphertext_hi) =
2646+ if let Some ( proof_data_with_ciphertext) =
2647+ transfer_amount_ciphertext_validity_proof_data_with_ciphertext
2648+ {
2649+ (
2650+ proof_data_with_ciphertext. ciphertext_lo ,
2651+ proof_data_with_ciphertext. ciphertext_hi ,
2652+ )
2653+ } else {
2654+ // unwrap is safe as long as either `proof_data_with_ciphertext`,
2655+ // `proof_account_with_ciphertext` is `Some(..)`, which is guaranteed by the
2656+ // previous check
2657+ (
2658+ transfer_amount_ciphertext_validity_proof_account_with_ciphertext
2659+ . unwrap ( )
2660+ . ciphertext_lo ,
2661+ transfer_amount_ciphertext_validity_proof_account_with_ciphertext
2662+ . unwrap ( )
2663+ . ciphertext_hi ,
2664+ )
2665+ } ;
2666+
26182667 // cannot panic as long as either `proof_data` or `proof_account` is `Some(..)`,
26192668 // which is guaranteed by the previous check
26202669 let equality_proof_location = Self :: confidential_transfer_create_proof_location (
@@ -2623,10 +2672,14 @@ where
26232672 1 ,
26242673 )
26252674 . unwrap ( ) ;
2675+ let transfer_amount_ciphertext_validity_proof_data =
2676+ transfer_amount_ciphertext_validity_proof_data_with_ciphertext
2677+ . map ( |data| data. proof_data ) ;
26262678 let transfer_amount_ciphertext_validity_proof_location =
26272679 Self :: confidential_transfer_create_proof_location (
26282680 transfer_amount_ciphertext_validity_proof_data. as_ref ( ) ,
2629- transfer_amount_ciphertext_validity_proof_account,
2681+ transfer_amount_ciphertext_validity_proof_account_with_ciphertext
2682+ . map ( |account| & account. proof_account ) ,
26302683 2 ,
26312684 )
26322685 . unwrap ( ) ;
@@ -2660,6 +2713,8 @@ where
26602713 self . get_address ( ) ,
26612714 destination_account,
26622715 new_decryptable_available_balance. into ( ) ,
2716+ & transfer_amount_auditor_ciphertext_lo,
2717+ & transfer_amount_auditor_ciphertext_hi,
26632718 source_authority,
26642719 & multisig_signers,
26652720 equality_proof_location,
0 commit comments