11use {
2- crate :: { encryption:: MintAmountCiphertext , errors:: TokenProofGenerationError , try_split_u64} ,
2+ crate :: {
3+ encryption:: MintAmountCiphertext , errors:: TokenProofGenerationError ,
4+ try_combine_lo_hi_ciphertexts, try_split_u64,
5+ } ,
36 solana_zk_sdk:: {
4- encryption:: { elgamal:: ElGamalPubkey , pedersen:: Pedersen } ,
7+ encryption:: {
8+ auth_encryption:: { AeCiphertext , AeKey } ,
9+ elgamal:: { ElGamalCiphertext , ElGamalKeypair , ElGamalPubkey } ,
10+ pedersen:: Pedersen ,
11+ } ,
512 zk_elgamal_proof_program:: proof_data:: {
6- BatchedGroupedCiphertext3HandlesValidityProofData , BatchedRangeProofU64Data ,
13+ BatchedGroupedCiphertext3HandlesValidityProofData , BatchedRangeProofU128Data ,
14+ CiphertextCommitmentEqualityProofData ,
715 } ,
816 } ,
917} ;
1018
19+ const NEW_SUPPLY_BIT_LENGTH : usize = 64 ;
1120const MINT_AMOUNT_LO_BIT_LENGTH : usize = 16 ;
1221const MINT_AMOUNT_HI_BIT_LENGTH : usize = 32 ;
1322/// The padding bit length in range proofs to make the bit-length power-of-2
1423const RANGE_PROOF_PADDING_BIT_LENGTH : usize = 16 ;
1524
1625/// The proof data required for a confidential mint instruction
1726pub struct MintProofData {
27+ pub equality_proof_data : CiphertextCommitmentEqualityProofData ,
1828 pub ciphertext_validity_proof_data : BatchedGroupedCiphertext3HandlesValidityProofData ,
19- pub range_proof_data : BatchedRangeProofU64Data ,
29+ pub range_proof_data : BatchedRangeProofU128Data ,
2030}
2131
2232pub fn mint_split_proof_data (
33+ current_supply_ciphertext : & ElGamalCiphertext ,
34+ current_decryptable_supply : & AeCiphertext ,
2335 mint_amount : u64 ,
36+ supply_elgamal_keypair : & ElGamalKeypair ,
37+ supply_aes_key : & AeKey ,
2438 destination_elgamal_pubkey : & ElGamalPubkey ,
2539 auditor_elgamal_pubkey : & ElGamalPubkey ,
26- supply_elgamal_pubkey : & ElGamalPubkey ,
2740) -> Result < MintProofData , TokenProofGenerationError > {
2841 // split the mint amount into low and high bits
2942 let ( mint_amount_lo, mint_amount_hi) = try_split_u64 ( mint_amount, MINT_AMOUNT_LO_BIT_LENGTH )
@@ -35,21 +48,62 @@ pub fn mint_split_proof_data(
3548 mint_amount_lo,
3649 destination_elgamal_pubkey,
3750 auditor_elgamal_pubkey,
38- supply_elgamal_pubkey ,
51+ supply_elgamal_keypair . pubkey ( ) ,
3952 ) ;
4053
4154 let ( mint_amount_grouped_ciphertext_hi, mint_amount_opening_hi) = MintAmountCiphertext :: new (
4255 mint_amount_hi,
4356 destination_elgamal_pubkey,
4457 auditor_elgamal_pubkey,
45- supply_elgamal_pubkey ,
58+ supply_elgamal_keypair . pubkey ( ) ,
4659 ) ;
4760
61+ // compute the new supply ciphertext
62+ let mint_amount_ciphertext_supply_lo = mint_amount_grouped_ciphertext_lo
63+ . 0
64+ . to_elgamal_ciphertext ( 2 )
65+ . unwrap ( ) ;
66+ let mint_amount_ciphertext_supply_hi = mint_amount_grouped_ciphertext_hi
67+ . 0
68+ . to_elgamal_ciphertext ( 2 )
69+ . unwrap ( ) ;
70+
71+ #[ allow( clippy:: arithmetic_side_effects) ]
72+ let new_supply_ciphertext = current_supply_ciphertext
73+ + try_combine_lo_hi_ciphertexts (
74+ & mint_amount_ciphertext_supply_lo,
75+ & mint_amount_ciphertext_supply_hi,
76+ MINT_AMOUNT_LO_BIT_LENGTH ,
77+ )
78+ . ok_or ( TokenProofGenerationError :: IllegalAmountBitLength ) ?;
79+
80+ // decrypt the current supply
81+ let current_supply = current_decryptable_supply
82+ . decrypt ( supply_aes_key)
83+ . ok_or ( TokenProofGenerationError :: IllegalAmountBitLength ) ?;
84+
85+ // compute the new supply
86+ let new_supply = current_supply
87+ . checked_add ( mint_amount)
88+ . ok_or ( TokenProofGenerationError :: IllegalAmountBitLength ) ?;
89+
90+ let ( new_supply_commitment, new_supply_opening) = Pedersen :: new ( new_supply) ;
91+
92+ // generate equality proof data
93+ let equality_proof_data = CiphertextCommitmentEqualityProofData :: new (
94+ supply_elgamal_keypair,
95+ & new_supply_ciphertext,
96+ & new_supply_commitment,
97+ & new_supply_opening,
98+ new_supply,
99+ )
100+ . map_err ( TokenProofGenerationError :: from) ?;
101+
48102 // generate ciphertext validity proof data
49103 let ciphertext_validity_proof_data = BatchedGroupedCiphertext3HandlesValidityProofData :: new (
50104 destination_elgamal_pubkey,
51105 auditor_elgamal_pubkey,
52- supply_elgamal_pubkey ,
106+ supply_elgamal_keypair . pubkey ( ) ,
53107 & mint_amount_grouped_ciphertext_lo. 0 ,
54108 & mint_amount_grouped_ciphertext_hi. 0 ,
55109 mint_amount_lo,
@@ -61,19 +115,22 @@ pub fn mint_split_proof_data(
61115
62116 // generate range proof data
63117 let ( padding_commitment, padding_opening) = Pedersen :: new ( 0_u64 ) ;
64- let range_proof_data = BatchedRangeProofU64Data :: new (
118+ let range_proof_data = BatchedRangeProofU128Data :: new (
65119 vec ! [
120+ & new_supply_commitment,
66121 mint_amount_grouped_ciphertext_lo. get_commitment( ) ,
67122 mint_amount_grouped_ciphertext_hi. get_commitment( ) ,
68123 & padding_commitment,
69124 ] ,
70- vec ! [ mint_amount_lo, mint_amount_hi, 0 ] ,
125+ vec ! [ new_supply , mint_amount_lo, mint_amount_hi, 0 ] ,
71126 vec ! [
127+ NEW_SUPPLY_BIT_LENGTH ,
72128 MINT_AMOUNT_LO_BIT_LENGTH ,
73129 MINT_AMOUNT_HI_BIT_LENGTH ,
74130 RANGE_PROOF_PADDING_BIT_LENGTH ,
75131 ] ,
76132 vec ! [
133+ & new_supply_opening,
77134 & mint_amount_opening_lo,
78135 & mint_amount_opening_hi,
79136 & padding_opening,
@@ -82,6 +139,7 @@ pub fn mint_split_proof_data(
82139 . map_err ( TokenProofGenerationError :: from) ?;
83140
84141 Ok ( MintProofData {
142+ equality_proof_data,
85143 ciphertext_validity_proof_data,
86144 range_proof_data,
87145 } )
0 commit comments