gorb_ctpg/
encryption.rs

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        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`,
34        // which holds exactly three decryption handles.
35        self.0.handles.first().unwrap()
36    }
37
38    pub fn get_destination_handle(&self) -> &DecryptHandle {
39        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`,
40        // which holds exactly three decryption handles.
41        self.0.handles.get(1).unwrap()
42    }
43
44    pub fn get_auditor_handle(&self) -> &DecryptHandle {
45        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`,
46        // which holds exactly three decryption handles.
47        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        // `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
79        // exactly two decryption handles.
80        self.0.handles.first().unwrap()
81    }
82
83    pub fn get_withdraw_withheld_authority_handle(&self) -> &DecryptHandle {
84        // `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
85        // exactly two decryption handles.
86        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}