pub use bytemuck::{Pod, Zeroable}; use { crate::zk_token_proof_instruction::ProofType, base64::{prelude::BASE64_STANDARD, Engine}, num_traits::{FromPrimitive, ToPrimitive}, solana_program::instruction::InstructionError, std::fmt, }; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] pub struct PodU16([u8; 2]); impl From for PodU16 { fn from(n: u16) -> Self { Self(n.to_le_bytes()) } } impl From for u16 { fn from(pod: PodU16) -> Self { Self::from_le_bytes(pod.0) } } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] pub struct PodU64([u8; 8]); impl From for PodU64 { fn from(n: u64) -> Self { Self(n.to_le_bytes()) } } impl From for u64 { fn from(pod: PodU64) -> Self { Self::from_le_bytes(pod.0) } } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] pub struct PodProofType(u8); impl From for PodProofType { fn from(proof_type: ProofType) -> Self { Self(ToPrimitive::to_u8(&proof_type).unwrap()) } } impl TryFrom for ProofType { type Error = InstructionError; fn try_from(pod: PodProofType) -> Result { FromPrimitive::from_u8(pod.0).ok_or(Self::Error::InvalidAccountData) } } #[derive(Clone, Copy, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct CompressedRistretto(pub [u8; 32]); #[derive(Clone, Copy, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct ElGamalCiphertext(pub [u8; 64]); impl fmt::Debug for ElGamalCiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } impl fmt::Display for ElGamalCiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", BASE64_STANDARD.encode(self.0)) } } impl Default for ElGamalCiphertext { fn default() -> Self { Self::zeroed() } } #[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct ElGamalPubkey(pub [u8; 32]); impl fmt::Debug for ElGamalPubkey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } impl fmt::Display for ElGamalPubkey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", BASE64_STANDARD.encode(self.0)) } } #[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct PedersenCommitment(pub [u8; 32]); impl fmt::Debug for PedersenCommitment { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } #[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct DecryptHandle(pub [u8; 32]); impl fmt::Debug for DecryptHandle { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } /// Serialization of `CtxtCommEqualityProof` #[derive(Clone, Copy)] #[repr(transparent)] pub struct CtxtCommEqualityProof(pub [u8; 192]); // `CtxtCommEqualityProof` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for CtxtCommEqualityProof {} unsafe impl Pod for CtxtCommEqualityProof {} /// Serialization of `CtxtCtxtEqualityProof` #[derive(Clone, Copy)] #[repr(transparent)] pub struct CtxtCtxtEqualityProof(pub [u8; 224]); // `CtxtCtxtEqualityProof` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for CtxtCtxtEqualityProof {} unsafe impl Pod for CtxtCtxtEqualityProof {} /// Serialization of validity proofs #[derive(Clone, Copy)] #[repr(transparent)] pub struct ValidityProof(pub [u8; 160]); // `ValidityProof` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for ValidityProof {} unsafe impl Pod for ValidityProof {} /// Serialization of aggregated validity proofs #[derive(Clone, Copy)] #[repr(transparent)] pub struct AggregatedValidityProof(pub [u8; 160]); // `AggregatedValidityProof` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for AggregatedValidityProof {} unsafe impl Pod for AggregatedValidityProof {} /// Serialization of zero balance proofs #[derive(Clone, Copy)] #[repr(transparent)] pub struct ZeroBalanceProof(pub [u8; 96]); // `ZeroBalanceProof` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for ZeroBalanceProof {} unsafe impl Pod for ZeroBalanceProof {} /// Serialization of fee sigma proof #[derive(Clone, Copy, Pod, Zeroable)] #[repr(transparent)] pub struct FeeSigmaProof(pub [u8; 256]); /// Serialization of public-key sigma proof #[derive(Clone, Copy, Pod, Zeroable)] #[repr(transparent)] pub struct PubkeySigmaProof(pub [u8; 64]); /// Serialization of range proofs for 64-bit numbers (for `Withdraw` instruction) #[derive(Clone, Copy)] #[repr(transparent)] pub struct RangeProof64(pub [u8; 672]); // `PodRangeProof64` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for RangeProof64 {} unsafe impl Pod for RangeProof64 {} /// Serialization of range proofs for 128-bit numbers (for `TransferRangeProof` instruction) #[derive(Clone, Copy)] #[repr(transparent)] pub struct RangeProof128(pub [u8; 736]); // `PodRangeProof128` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for RangeProof128 {} unsafe impl Pod for RangeProof128 {} /// Serialization of range proofs for 128-bit numbers (for `TransferRangeProof` instruction) #[derive(Clone, Copy)] #[repr(transparent)] pub struct RangeProof256(pub [u8; 800]); // `PodRangeProof256` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for RangeProof256 {} unsafe impl Pod for RangeProof256 {} /// Serialization for AeCiphertext #[derive(Clone, Copy, PartialEq, Eq)] #[repr(transparent)] pub struct AeCiphertext(pub [u8; 36]); // `AeCiphertext` is a Pod and Zeroable. // Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays unsafe impl Zeroable for AeCiphertext {} unsafe impl Pod for AeCiphertext {} impl fmt::Debug for AeCiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) } } impl fmt::Display for AeCiphertext { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", BASE64_STANDARD.encode(self.0)) } } impl Default for AeCiphertext { fn default() -> Self { Self::zeroed() } } // TODO: refactor this code into the instruction module #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct TransferPubkeys { pub source_pubkey: ElGamalPubkey, pub destination_pubkey: ElGamalPubkey, pub auditor_pubkey: ElGamalPubkey, } #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct TransferWithFeePubkeys { pub source_pubkey: ElGamalPubkey, pub destination_pubkey: ElGamalPubkey, pub auditor_pubkey: ElGamalPubkey, pub withdraw_withheld_authority_pubkey: ElGamalPubkey, } #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct TransferAmountEncryption { pub commitment: PedersenCommitment, pub source_handle: DecryptHandle, pub destination_handle: DecryptHandle, pub auditor_handle: DecryptHandle, } #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct FeeEncryption { pub commitment: PedersenCommitment, pub destination_handle: DecryptHandle, pub withdraw_withheld_authority_handle: DecryptHandle, } #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct FeeParameters { /// Fee rate expressed as basis points of the transfer amount, i.e. increments of 0.01% pub fee_rate_basis_points: PodU16, /// Maximum fee assessed on transfers, expressed as an amount of tokens pub maximum_fee: PodU64, }