1use solana_zk_sdk::encryption::{
2 elgamal::{DecryptHandle, ElGamalPubkey},
3 grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
4 pedersen::{PedersenCommitment, PedersenOpening},
5};
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(C)]
9pub struct TransferAmountCiphertext(pub(crate) GroupedElGamalCiphertext<3>);
10
11impl TransferAmountCiphertext {
12 pub fn new(
13 amount: u64,
14 source_pubkey: &ElGamalPubkey,
15 destination_pubkey: &ElGamalPubkey,
16 auditor_pubkey: &ElGamalPubkey,
17 ) -> (Self, PedersenOpening) {
18 let opening = PedersenOpening::new_rand();
19 let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with(
20 [source_pubkey, destination_pubkey, auditor_pubkey],
21 amount,
22 &opening,
23 );
24
25 (Self(grouped_ciphertext), opening)
26 }
27
28 pub fn get_commitment(&self) -> &PedersenCommitment {
29 &self.0.commitment
30 }
31
32 pub fn get_source_handle(&self) -> &DecryptHandle {
33 self.0.handles.first().unwrap()
36 }
37
38 pub fn get_destination_handle(&self) -> &DecryptHandle {
39 self.0.handles.get(1).unwrap()
42 }
43
44 pub fn get_auditor_handle(&self) -> &DecryptHandle {
45 self.0.handles.get(2).unwrap()
48 }
49}
50
51#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52#[repr(C)]
53#[cfg(not(target_os = "solana"))]
54pub struct FeeCiphertext(pub(crate) GroupedElGamalCiphertext<2>);
55
56#[cfg(not(target_os = "solana"))]
57impl FeeCiphertext {
58 pub fn new(
59 amount: u64,
60 destination_pubkey: &ElGamalPubkey,
61 withdraw_withheld_authority_pubkey: &ElGamalPubkey,
62 ) -> (Self, PedersenOpening) {
63 let opening = PedersenOpening::new_rand();
64 let grouped_ciphertext = GroupedElGamal::<2>::encrypt_with(
65 [destination_pubkey, withdraw_withheld_authority_pubkey],
66 amount,
67 &opening,
68 );
69
70 (Self(grouped_ciphertext), opening)
71 }
72
73 pub fn get_commitment(&self) -> &PedersenCommitment {
74 &self.0.commitment
75 }
76
77 pub fn get_destination_handle(&self) -> &DecryptHandle {
78 self.0.handles.first().unwrap()
81 }
82
83 pub fn get_withdraw_withheld_authority_handle(&self) -> &DecryptHandle {
84 self.0.handles.get(1).unwrap()
87 }
88}
89
90#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91#[repr(C)]
92pub struct BurnAmountCiphertext(pub(crate) GroupedElGamalCiphertext<3>);
93
94impl BurnAmountCiphertext {
95 pub fn new(
96 amount: u64,
97 source_pubkey: &ElGamalPubkey,
98 auditor_pubkey: &ElGamalPubkey,
99 supply_pubkey: &ElGamalPubkey,
100 ) -> (Self, PedersenOpening) {
101 let opening = PedersenOpening::new_rand();
102 let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with(
103 [source_pubkey, auditor_pubkey, supply_pubkey],
104 amount,
105 &opening,
106 );
107
108 (Self(grouped_ciphertext), opening)
109 }
110
111 pub fn get_commitment(&self) -> &PedersenCommitment {
112 &self.0.commitment
113 }
114}
115
116#[derive(Clone, Copy, Debug, Eq, PartialEq)]
117#[repr(C)]
118pub struct MintAmountCiphertext(pub(crate) GroupedElGamalCiphertext<3>);
119
120impl MintAmountCiphertext {
121 pub fn new(
122 amount: u64,
123 source_pubkey: &ElGamalPubkey,
124 auditor_pubkey: &ElGamalPubkey,
125 supply_pubkey: &ElGamalPubkey,
126 ) -> (Self, PedersenOpening) {
127 let opening = PedersenOpening::new_rand();
128 let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with(
129 [source_pubkey, auditor_pubkey, supply_pubkey],
130 amount,
131 &opening,
132 );
133
134 (Self(grouped_ciphertext), opening)
135 }
136
137 pub fn get_commitment(&self) -> &PedersenCommitment {
138 &self.0.commitment
139 }
140}