1use {
2 curve25519_dalek::scalar::Scalar,
3 solana_zk_sdk::{
4 encryption::{
5 elgamal::ElGamalCiphertext,
6 pedersen::{PedersenCommitment, PedersenOpening},
7 pod::elgamal::PodElGamalCiphertext,
8 },
9 zk_elgamal_proof_program::proof_data::BatchedGroupedCiphertext3HandlesValidityProofData,
10 },
11};
12
13pub mod burn;
14pub mod encryption;
15pub mod errors;
16pub mod mint;
17pub mod transfer;
18pub mod transfer_with_fee;
19pub mod withdraw;
20
21pub const TRANSFER_AMOUNT_LO_BITS: usize = 16;
23pub const TRANSFER_AMOUNT_HI_BITS: usize = 32;
25pub const REMAINING_BALANCE_BIT_LENGTH: usize = 64;
27
28pub fn try_split_u64(amount: u64, bit_length: usize) -> Option<(u64, u64)> {
32 match bit_length {
33 0 => Some((0, amount)),
34 1..=63 => {
35 let bit_length_complement = u64::BITS.checked_sub(bit_length as u32).unwrap();
36 let lo = amount
38 .checked_shl(bit_length_complement)?
39 .checked_shr(bit_length_complement)?;
40 let hi = amount.checked_shr(bit_length as u32)?;
41 Some((lo, hi))
42 }
43 64 => Some((amount, 0)),
44 _ => None,
45 }
46}
47
48pub fn try_combine_lo_hi_u64(amount_lo: u64, amount_hi: u64, bit_length: usize) -> Option<u64> {
52 match bit_length {
53 0 => Some(amount_hi),
54 1..=63 => {
55 amount_hi
57 .checked_shl(bit_length as u32)?
58 .checked_add(amount_hi)
59 }
60 64 => Some(amount_lo),
61 _ => None,
62 }
63}
64
65#[allow(clippy::arithmetic_side_effects)]
66pub fn try_combine_lo_hi_ciphertexts(
67 ciphertext_lo: &ElGamalCiphertext,
68 ciphertext_hi: &ElGamalCiphertext,
69 bit_length: usize,
70) -> Option<ElGamalCiphertext> {
71 let two_power = 1_u64.checked_shl(bit_length as u32)?;
72 Some(ciphertext_lo + ciphertext_hi * Scalar::from(two_power))
73}
74
75#[allow(clippy::arithmetic_side_effects)]
76pub fn try_combine_lo_hi_commitments(
77 comm_lo: &PedersenCommitment,
78 comm_hi: &PedersenCommitment,
79 bit_length: usize,
80) -> Option<PedersenCommitment> {
81 let two_power = 1_u64.checked_shl(bit_length as u32)?;
82 Some(comm_lo + comm_hi * Scalar::from(two_power))
83}
84
85#[allow(clippy::arithmetic_side_effects)]
86pub fn try_combine_lo_hi_openings(
87 opening_lo: &PedersenOpening,
88 opening_hi: &PedersenOpening,
89 bit_length: usize,
90) -> Option<PedersenOpening> {
91 let two_power = 1_u64.checked_shl(bit_length as u32)?;
92 Some(opening_lo + opening_hi * Scalar::from(two_power))
93}
94
95#[derive(Clone, Copy)]
104pub struct CiphertextValidityProofWithAuditorCiphertext {
105 pub proof_data: BatchedGroupedCiphertext3HandlesValidityProofData,
106 pub ciphertext_lo: PodElGamalCiphertext,
107 pub ciphertext_hi: PodElGamalCiphertext,
108}