solana_zk_token_sdk/instruction/transfer/
encryption.rs

1#[cfg(not(target_os = "solana"))]
2use crate::encryption::{
3    elgamal::{DecryptHandle, ElGamalPubkey},
4    grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
5    pedersen::{PedersenCommitment, PedersenOpening},
6};
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9#[repr(C)]
10#[cfg(not(target_os = "solana"))]
11pub struct TransferAmountCiphertext(pub(crate) GroupedElGamalCiphertext<3>);
12
13#[cfg(not(target_os = "solana"))]
14impl TransferAmountCiphertext {
15    pub fn new(
16        amount: u64,
17        source_pubkey: &ElGamalPubkey,
18        destination_pubkey: &ElGamalPubkey,
19        auditor_pubkey: &ElGamalPubkey,
20    ) -> (Self, PedersenOpening) {
21        let opening = PedersenOpening::new_rand();
22        let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with(
23            [source_pubkey, destination_pubkey, auditor_pubkey],
24            amount,
25            &opening,
26        );
27
28        (Self(grouped_ciphertext), opening)
29    }
30
31    pub fn get_commitment(&self) -> &PedersenCommitment {
32        &self.0.commitment
33    }
34
35    pub fn get_source_handle(&self) -> &DecryptHandle {
36        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which
37        // holds exactly three decryption handles.
38        self.0.handles.first().unwrap()
39    }
40
41    pub fn get_destination_handle(&self) -> &DecryptHandle {
42        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which holds
43        // exactly three decryption handles.
44        self.0.handles.get(1).unwrap()
45    }
46
47    pub fn get_auditor_handle(&self) -> &DecryptHandle {
48        // `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which holds
49        // exactly three decryption handles.
50        self.0.handles.get(2).unwrap()
51    }
52}
53
54#[derive(Clone, Copy, Debug, Eq, PartialEq)]
55#[repr(C)]
56#[cfg(not(target_os = "solana"))]
57pub struct FeeEncryption(pub(crate) GroupedElGamalCiphertext<2>);
58
59#[cfg(not(target_os = "solana"))]
60impl FeeEncryption {
61    pub fn new(
62        amount: u64,
63        destination_pubkey: &ElGamalPubkey,
64        withdraw_withheld_authority_pubkey: &ElGamalPubkey,
65    ) -> (Self, PedersenOpening) {
66        let opening = PedersenOpening::new_rand();
67        let grouped_ciphertext = GroupedElGamal::<2>::encrypt_with(
68            [destination_pubkey, withdraw_withheld_authority_pubkey],
69            amount,
70            &opening,
71        );
72
73        (Self(grouped_ciphertext), opening)
74    }
75
76    pub fn get_commitment(&self) -> &PedersenCommitment {
77        &self.0.commitment
78    }
79
80    pub fn get_destination_handle(&self) -> &DecryptHandle {
81        // `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
82        // exactly two decryption handles.
83        self.0.handles.first().unwrap()
84    }
85
86    pub fn get_withdraw_withheld_authority_handle(&self) -> &DecryptHandle {
87        // `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
88        // exactly two decryption handles.
89        self.0.handles.get(1).unwrap()
90    }
91}