From 49305cc5b017a6acbed0150376d4188ebd64821c Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 15:42:58 +0900 Subject: [PATCH 01/11] refactor `PodU16`, `PodU64`, `PodProofType` --- zk-token-sdk/src/zk_token_elgamal/mod.rs | 52 ++++++++++++++++++++++++ zk-token-sdk/src/zk_token_elgamal/pod.rs | 48 +--------------------- zk-token-sdk/src/zk_token_proof_state.rs | 2 +- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/zk-token-sdk/src/zk_token_elgamal/mod.rs b/zk-token-sdk/src/zk_token_elgamal/mod.rs index 73a4ce08e8a312..6d2389f3ffd2b5 100644 --- a/zk-token-sdk/src/zk_token_elgamal/mod.rs +++ b/zk-token-sdk/src/zk_token_elgamal/mod.rs @@ -1,4 +1,56 @@ +pub use bytemuck::{Pod, Zeroable}; + +use { + crate::zk_token_proof_instruction::ProofType, + num_traits::{FromPrimitive, ToPrimitive}, + solana_program::instruction::InstructionError, +}; + pub mod convert; pub mod decryption; pub mod ops; pub mod pod; + +#[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) + } +} diff --git a/zk-token-sdk/src/zk_token_elgamal/pod.rs b/zk-token-sdk/src/zk_token_elgamal/pod.rs index f76681a9633f7a..edaaeac6adab96 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod.rs @@ -1,56 +1,10 @@ pub use bytemuck::{Pod, Zeroable}; use { - crate::zk_token_proof_instruction::ProofType, + crate::zk_token_elgamal::{PodU16, PodU64}, 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]); diff --git a/zk-token-sdk/src/zk_token_proof_state.rs b/zk-token-sdk/src/zk_token_proof_state.rs index d95aa4f11ec1c3..6fc2e0b663e25d 100644 --- a/zk-token-sdk/src/zk_token_proof_state.rs +++ b/zk-token-sdk/src/zk_token_proof_state.rs @@ -1,5 +1,5 @@ use { - crate::{zk_token_elgamal::pod::PodProofType, zk_token_proof_instruction::ProofType}, + crate::{zk_token_elgamal::PodProofType, zk_token_proof_instruction::ProofType}, bytemuck::{bytes_of, Pod, Zeroable}, num_traits::ToPrimitive, solana_program::{ From e2461c135ac6cbe73d325fa08a2651368bdfa602 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 16:18:41 +0900 Subject: [PATCH 02/11] refactor elgamal and pedersen pod types into separate submodules --- zk-token-sdk/src/zk_token_elgamal/convert.rs | 169 +++++------------- zk-token-sdk/src/zk_token_elgamal/elgamal.rs | 114 ++++++++++++ zk-token-sdk/src/zk_token_elgamal/mod.rs | 16 +- zk-token-sdk/src/zk_token_elgamal/ops.rs | 72 ++++---- zk-token-sdk/src/zk_token_elgamal/pedersen.rs | 43 +++++ zk-token-sdk/src/zk_token_elgamal/pod.rs | 60 +------ 6 files changed, 247 insertions(+), 227 deletions(-) create mode 100644 zk-token-sdk/src/zk_token_elgamal/elgamal.rs create mode 100644 zk-token-sdk/src/zk_token_elgamal/pedersen.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/convert.rs b/zk-token-sdk/src/zk_token_elgamal/convert.rs index 00a582be21c260..2f9db2f1540275 100644 --- a/zk-token-sdk/src/zk_token_elgamal/convert.rs +++ b/zk-token-sdk/src/zk_token_elgamal/convert.rs @@ -1,50 +1,50 @@ pub use target_arch::*; use {super::pod, crate::curve25519::ristretto::PodRistrettoPoint}; -impl From<(pod::PedersenCommitment, pod::DecryptHandle)> for pod::ElGamalCiphertext { - fn from((commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle)) -> Self { - let mut buf = [0_u8; 64]; - buf[..32].copy_from_slice(&commitment.0); - buf[32..].copy_from_slice(&handle.0); - pod::ElGamalCiphertext(buf) - } -} - -impl From for (pod::PedersenCommitment, pod::DecryptHandle) { - fn from(ciphertext: pod::ElGamalCiphertext) -> Self { - let commitment: [u8; 32] = ciphertext.0[..32].try_into().unwrap(); - let handle: [u8; 32] = ciphertext.0[32..].try_into().unwrap(); - - ( - pod::PedersenCommitment(commitment), - pod::DecryptHandle(handle), - ) - } -} - -impl From for PodRistrettoPoint { - fn from(commitment: pod::PedersenCommitment) -> Self { - PodRistrettoPoint(commitment.0) - } -} - -impl From for pod::PedersenCommitment { - fn from(point: PodRistrettoPoint) -> Self { - pod::PedersenCommitment(point.0) - } -} - -impl From for PodRistrettoPoint { - fn from(handle: pod::DecryptHandle) -> Self { - PodRistrettoPoint(handle.0) - } -} - -impl From for pod::DecryptHandle { - fn from(point: PodRistrettoPoint) -> Self { - pod::DecryptHandle(point.0) - } -} +// impl From<(pod::PedersenCommitment, pod::DecryptHandle)> for pod::ElGamalCiphertext { +// fn from((commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle)) -> Self { +// let mut buf = [0_u8; 64]; +// buf[..32].copy_from_slice(&commitment.0); +// buf[32..].copy_from_slice(&handle.0); +// pod::ElGamalCiphertext(buf) +// } +// } + +// impl From for (pod::PedersenCommitment, pod::DecryptHandle) { +// fn from(ciphertext: pod::ElGamalCiphertext) -> Self { +// let commitment: [u8; 32] = ciphertext.0[..32].try_into().unwrap(); +// let handle: [u8; 32] = ciphertext.0[32..].try_into().unwrap(); + +// ( +// pod::PedersenCommitment(commitment), +// pod::DecryptHandle(handle), +// ) +// } +// } + +// impl From for PodRistrettoPoint { +// fn from(commitment: pod::PedersenCommitment) -> Self { +// PodRistrettoPoint(commitment.0) +// } +// } + +// impl From for pod::PedersenCommitment { +// fn from(point: PodRistrettoPoint) -> Self { +// pod::PedersenCommitment(point.0) +// } +// } + +// impl From for PodRistrettoPoint { +// fn from(handle: pod::DecryptHandle) -> Self { +// PodRistrettoPoint(handle.0) +// } +// } + +// impl From for pod::DecryptHandle { +// fn from(point: PodRistrettoPoint) -> Self { +// pod::DecryptHandle(point.0) +// } +// } #[cfg(not(target_os = "solana"))] mod target_arch { @@ -52,11 +52,7 @@ mod target_arch { super::pod, crate::{ curve25519::scalar::PodScalar, - encryption::{ - auth_encryption::AeCiphertext, - elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, - pedersen::PedersenCommitment, - }, + encryption::auth_encryption::AeCiphertext, errors::{ProofError, ProofVerificationError}, instruction::{ transfer::{TransferAmountEncryption, TransferPubkeys}, @@ -91,34 +87,6 @@ mod target_arch { } } - impl From for pod::ElGamalCiphertext { - fn from(ct: ElGamalCiphertext) -> Self { - Self(ct.to_bytes()) - } - } - - impl TryFrom for ElGamalCiphertext { - type Error = ProofError; - - fn try_from(ct: pod::ElGamalCiphertext) -> Result { - Self::from_bytes(&ct.0).ok_or(ProofError::CiphertextDeserialization) - } - } - - impl From for pod::ElGamalPubkey { - fn from(pk: ElGamalPubkey) -> Self { - Self(pk.to_bytes()) - } - } - - impl TryFrom for ElGamalPubkey { - type Error = ProofError; - - fn try_from(pk: pod::ElGamalPubkey) -> Result { - Self::from_bytes(&pk.0).ok_or(ProofError::CiphertextDeserialization) - } - } - impl From for pod::CompressedRistretto { fn from(cr: CompressedRistretto) -> Self { Self(cr.to_bytes()) @@ -131,53 +99,6 @@ mod target_arch { } } - impl From for pod::PedersenCommitment { - fn from(comm: PedersenCommitment) -> Self { - Self(comm.to_bytes()) - } - } - - // For proof verification, interpret pod::PedersenComm directly as CompressedRistretto - #[cfg(not(target_os = "solana"))] - impl From for CompressedRistretto { - fn from(pod: pod::PedersenCommitment) -> Self { - Self(pod.0) - } - } - - #[cfg(not(target_os = "solana"))] - impl TryFrom for PedersenCommitment { - type Error = ProofError; - - fn try_from(pod: pod::PedersenCommitment) -> Result { - Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) - } - } - - #[cfg(not(target_os = "solana"))] - impl From for pod::DecryptHandle { - fn from(handle: DecryptHandle) -> Self { - Self(handle.to_bytes()) - } - } - - // For proof verification, interpret pod::PedersenDecHandle as CompressedRistretto - #[cfg(not(target_os = "solana"))] - impl From for CompressedRistretto { - fn from(pod: pod::DecryptHandle) -> Self { - Self(pod.0) - } - } - - #[cfg(not(target_os = "solana"))] - impl TryFrom for DecryptHandle { - type Error = ProofError; - - fn try_from(pod: pod::DecryptHandle) -> Result { - Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) - } - } - impl From for pod::AeCiphertext { fn from(ct: AeCiphertext) -> Self { Self(ct.to_bytes()) diff --git a/zk-token-sdk/src/zk_token_elgamal/elgamal.rs b/zk-token-sdk/src/zk_token_elgamal/elgamal.rs new file mode 100644 index 00000000000000..e3691bd744bab1 --- /dev/null +++ b/zk-token-sdk/src/zk_token_elgamal/elgamal.rs @@ -0,0 +1,114 @@ +use { + crate::{ + encryption::elgamal, + errors::ProofError, + zk_token_elgamal::{Pod, Zeroable}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + curve25519_dalek::ristretto::CompressedRistretto, + std::fmt, +}; + +#[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)) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for ElGamalPubkey { + fn from(pk: elgamal::ElGamalPubkey) -> Self { + Self(pk.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for elgamal::ElGamalPubkey { + type Error = ProofError; + + fn try_from(pk: ElGamalPubkey) -> Result { + Self::from_bytes(&pk.0).ok_or(ProofError::CiphertextDeserialization) + } +} + +#[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() + } +} + +#[cfg(not(target_os = "solana"))] +impl From for ElGamalCiphertext { + fn from(ct: elgamal::ElGamalCiphertext) -> Self { + Self(ct.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for elgamal::ElGamalCiphertext { + type Error = ProofError; + + fn try_from(ct: ElGamalCiphertext) -> Result { + Self::from_bytes(&ct.0).ok_or(ProofError::CiphertextDeserialization) + } +} + +#[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) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for DecryptHandle { + fn from(handle: elgamal::DecryptHandle) -> Self { + Self(handle.to_bytes()) + } +} + +// For proof verification, interpret pod::PedersenDecHandle as CompressedRistretto +#[cfg(not(target_os = "solana"))] +impl From for CompressedRistretto { + fn from(pod: DecryptHandle) -> Self { + Self(pod.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for elgamal::DecryptHandle { + type Error = ProofError; + + fn try_from(pod: DecryptHandle) -> Result { + Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) + } +} diff --git a/zk-token-sdk/src/zk_token_elgamal/mod.rs b/zk-token-sdk/src/zk_token_elgamal/mod.rs index 6d2389f3ffd2b5..52b241c6288d57 100644 --- a/zk-token-sdk/src/zk_token_elgamal/mod.rs +++ b/zk-token-sdk/src/zk_token_elgamal/mod.rs @@ -1,4 +1,9 @@ -pub use bytemuck::{Pod, Zeroable}; +pub mod convert; +// pub mod decryption; +pub mod elgamal; +// pub mod ops; +pub mod pedersen; +pub mod pod; use { crate::zk_token_proof_instruction::ProofType, @@ -6,10 +11,11 @@ use { solana_program::instruction::InstructionError, }; -pub mod convert; -pub mod decryption; -pub mod ops; -pub mod pod; +pub use { + bytemuck::{Pod, Zeroable}, + elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, + pedersen::PedersenCommitment, +}; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] diff --git a/zk-token-sdk/src/zk_token_elgamal/ops.rs b/zk-token-sdk/src/zk_token_elgamal/ops.rs index fff1152f99b59d..c96ad970d53a25 100644 --- a/zk-token-sdk/src/zk_token_elgamal/ops.rs +++ b/zk-token-sdk/src/zk_token_elgamal/ops.rs @@ -3,7 +3,7 @@ use crate::{ ristretto::{add_ristretto, multiply_ristretto, subtract_ristretto, PodRistrettoPoint}, scalar::PodScalar, }, - zk_token_elgamal::pod, + zk_token_elgamal::{elgamal::*, pedersen::*}, }; const SHIFT_BITS: usize = 16; @@ -15,45 +15,42 @@ const G: PodRistrettoPoint = PodRistrettoPoint([ /// Add two ElGamal ciphertexts pub fn add( - left_ciphertext: &pod::ElGamalCiphertext, - right_ciphertext: &pod::ElGamalCiphertext, -) -> Option { - let (left_commitment, left_handle): (pod::PedersenCommitment, pod::DecryptHandle) = + left_ciphertext: &ElGamalCiphertext, + right_ciphertext: &ElGamalCiphertext, +) -> Option { + let (left_commitment, left_handle): (PedersenCommitment, DecryptHandle) = (*left_ciphertext).into(); - let (right_commitment, right_handle): (pod::PedersenCommitment, pod::DecryptHandle) = + let (right_commitment, right_handle): (PedersenCommitment, DecryptHandle) = (*right_ciphertext).into(); - let result_commitment: pod::PedersenCommitment = + let result_commitment: PedersenCommitment = add_ristretto(&left_commitment.into(), &right_commitment.into())?.into(); - let result_handle: pod::DecryptHandle = + let result_handle: DecryptHandle = add_ristretto(&left_handle.into(), &right_handle.into())?.into(); Some((result_commitment, result_handle).into()) } /// Multiply an ElGamal ciphertext by a scalar -pub fn multiply( - scalar: &PodScalar, - ciphertext: &pod::ElGamalCiphertext, -) -> Option { - let (commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle) = (*ciphertext).into(); +pub fn multiply(scalar: &PodScalar, ciphertext: &ElGamalCiphertext) -> Option { + let (commitment, handle): (PedersenCommitment, DecryptHandle) = (*ciphertext).into(); let commitment_point: PodRistrettoPoint = commitment.into(); let handle_point: PodRistrettoPoint = handle.into(); - let result_commitment: pod::PedersenCommitment = + let result_commitment: PedersenCommitment = multiply_ristretto(scalar, &commitment_point)?.into(); - let result_handle: pod::DecryptHandle = multiply_ristretto(scalar, &handle_point)?.into(); + let result_handle: DecryptHandle = multiply_ristretto(scalar, &handle_point)?.into(); Some((result_commitment, result_handle).into()) } /// Compute `left_ciphertext + (right_ciphertext_lo + 2^16 * right_ciphertext_hi)` pub fn add_with_lo_hi( - left_ciphertext: &pod::ElGamalCiphertext, - right_ciphertext_lo: &pod::ElGamalCiphertext, - right_ciphertext_hi: &pod::ElGamalCiphertext, -) -> Option { + left_ciphertext: &ElGamalCiphertext, + right_ciphertext_lo: &ElGamalCiphertext, + right_ciphertext_hi: &ElGamalCiphertext, +) -> Option { let shift_scalar = to_scalar(1_u64 << SHIFT_BITS); let shifted_right_ciphertext_hi = multiply(&shift_scalar, right_ciphertext_hi)?; let combined_right_ciphertext = add(right_ciphertext_lo, &shifted_right_ciphertext_hi)?; @@ -62,17 +59,17 @@ pub fn add_with_lo_hi( /// Subtract two ElGamal ciphertexts pub fn subtract( - left_ciphertext: &pod::ElGamalCiphertext, - right_ciphertext: &pod::ElGamalCiphertext, -) -> Option { - let (left_commitment, left_handle): (pod::PedersenCommitment, pod::DecryptHandle) = + left_ciphertext: &ElGamalCiphertext, + right_ciphertext: &ElGamalCiphertext, +) -> Option { + let (left_commitment, left_handle): (PedersenCommitment, DecryptHandle) = (*left_ciphertext).into(); - let (right_commitment, right_handle): (pod::PedersenCommitment, pod::DecryptHandle) = + let (right_commitment, right_handle): (PedersenCommitment, DecryptHandle) = (*right_ciphertext).into(); - let result_commitment: pod::PedersenCommitment = + let result_commitment: PedersenCommitment = subtract_ristretto(&left_commitment.into(), &right_commitment.into())?.into(); - let result_handle: pod::DecryptHandle = + let result_handle: DecryptHandle = subtract_ristretto(&left_handle.into(), &right_handle.into())?.into(); Some((result_commitment, result_handle).into()) @@ -80,10 +77,10 @@ pub fn subtract( /// Compute `left_ciphertext - (right_ciphertext_lo + 2^16 * right_ciphertext_hi)` pub fn subtract_with_lo_hi( - left_ciphertext: &pod::ElGamalCiphertext, - right_ciphertext_lo: &pod::ElGamalCiphertext, - right_ciphertext_hi: &pod::ElGamalCiphertext, -) -> Option { + left_ciphertext: &ElGamalCiphertext, + right_ciphertext_lo: &ElGamalCiphertext, + right_ciphertext_hi: &ElGamalCiphertext, +) -> Option { let shift_scalar = to_scalar(1_u64 << SHIFT_BITS); let shifted_right_ciphertext_hi = multiply(&shift_scalar, right_ciphertext_hi)?; let combined_right_ciphertext = add(right_ciphertext_lo, &shifted_right_ciphertext_hi)?; @@ -91,30 +88,27 @@ pub fn subtract_with_lo_hi( } /// Add a constant amount to a ciphertext -pub fn add_to(ciphertext: &pod::ElGamalCiphertext, amount: u64) -> Option { +pub fn add_to(ciphertext: &ElGamalCiphertext, amount: u64) -> Option { let amount_scalar = to_scalar(amount); let amount_point = multiply_ristretto(&amount_scalar, &G)?; - let (commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle) = (*ciphertext).into(); + let (commitment, handle): (PedersenCommitment, DecryptHandle) = (*ciphertext).into(); let commitment_point: PodRistrettoPoint = commitment.into(); - let result_commitment: pod::PedersenCommitment = + let result_commitment: PedersenCommitment = add_ristretto(&commitment_point, &amount_point)?.into(); Some((result_commitment, handle).into()) } /// Subtract a constant amount to a ciphertext -pub fn subtract_from( - ciphertext: &pod::ElGamalCiphertext, - amount: u64, -) -> Option { +pub fn subtract_from(ciphertext: &ElGamalCiphertext, amount: u64) -> Option { let amount_scalar = to_scalar(amount); let amount_point = multiply_ristretto(&amount_scalar, &G)?; - let (commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle) = (*ciphertext).into(); + let (commitment, handle): (PedersenCommitment, DecryptHandle) = (*ciphertext).into(); let commitment_point: PodRistrettoPoint = commitment.into(); - let result_commitment: pod::PedersenCommitment = + let result_commitment: PedersenCommitment = subtract_ristretto(&commitment_point, &amount_point)?.into(); Some((result_commitment, handle).into()) } diff --git a/zk-token-sdk/src/zk_token_elgamal/pedersen.rs b/zk-token-sdk/src/zk_token_elgamal/pedersen.rs new file mode 100644 index 00000000000000..6d76f6ac834f00 --- /dev/null +++ b/zk-token-sdk/src/zk_token_elgamal/pedersen.rs @@ -0,0 +1,43 @@ +use { + crate::{ + encryption::pedersen, + errors::ProofError, + zk_token_elgamal::{Pod, Zeroable}, + }, + curve25519_dalek::ristretto::CompressedRistretto, + std::fmt, +}; + +#[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) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for PedersenCommitment { + fn from(comm: pedersen::PedersenCommitment) -> Self { + Self(comm.to_bytes()) + } +} + +// For proof verification, interpret pod::PedersenComm directly as CompressedRistretto +#[cfg(not(target_os = "solana"))] +impl From for CompressedRistretto { + fn from(pod: PedersenCommitment) -> Self { + Self(pod.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for pedersen::PedersenCommitment { + type Error = ProofError; + + fn try_from(pod: PedersenCommitment) -> Result { + Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) + } +} diff --git a/zk-token-sdk/src/zk_token_elgamal/pod.rs b/zk-token-sdk/src/zk_token_elgamal/pod.rs index edaaeac6adab96..97c5dcb07542cd 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod.rs @@ -1,6 +1,6 @@ pub use bytemuck::{Pod, Zeroable}; use { - crate::zk_token_elgamal::{PodU16, PodU64}, + crate::zk_token_elgamal::{elgamal::*, pedersen::*, PodU16, PodU64}, base64::{prelude::BASE64_STANDARD, Engine}, std::fmt, }; @@ -9,64 +9,6 @@ use { #[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 `CiphertextCommitmentEqualityProof` #[derive(Clone, Copy)] #[repr(transparent)] From ad112f46e66df47e6fc6984c572416659af83308 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 16:24:34 +0900 Subject: [PATCH 03/11] rename `zk_token_elgamal` module to `pod` --- zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs | 2 +- zk-token-sdk/src/instruction/pubkey_validity.rs | 2 +- zk-token-sdk/src/instruction/transfer.rs | 2 +- zk-token-sdk/src/instruction/transfer_with_fee.rs | 2 +- zk-token-sdk/src/instruction/withdraw.rs | 2 +- zk-token-sdk/src/instruction/zero_balance.rs | 2 +- zk-token-sdk/src/lib.rs | 2 +- zk-token-sdk/src/{zk_token_elgamal => pod}/convert.rs | 0 zk-token-sdk/src/{zk_token_elgamal => pod}/decryption.rs | 0 zk-token-sdk/src/{zk_token_elgamal => pod}/elgamal.rs | 2 +- zk-token-sdk/src/{zk_token_elgamal => pod}/mod.rs | 0 zk-token-sdk/src/{zk_token_elgamal => pod}/ops.rs | 0 zk-token-sdk/src/{zk_token_elgamal => pod}/pedersen.rs | 2 +- zk-token-sdk/src/{zk_token_elgamal => pod}/pod.rs | 2 +- zk-token-sdk/src/transcript.rs | 2 +- zk-token-sdk/src/zk_token_proof_state.rs | 2 +- 16 files changed, 12 insertions(+), 12 deletions(-) rename zk-token-sdk/src/{zk_token_elgamal => pod}/convert.rs (100%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/decryption.rs (100%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/elgamal.rs (98%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/mod.rs (100%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/ops.rs (100%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/pedersen.rs (96%) rename zk-token-sdk/src/{zk_token_elgamal => pod}/pod.rs (98%) diff --git a/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs b/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs index de2e8e07de046f..c9bc50b19bbffb 100644 --- a/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs +++ b/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs @@ -25,7 +25,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/pubkey_validity.rs b/zk-token-sdk/src/instruction/pubkey_validity.rs index 699b18885b3e63..e877d01ad33889 100644 --- a/zk-token-sdk/src/instruction/pubkey_validity.rs +++ b/zk-token-sdk/src/instruction/pubkey_validity.rs @@ -17,7 +17,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/transfer.rs b/zk-token-sdk/src/instruction/transfer.rs index a153b6b3076f24..b9bb6bc6b22f74 100644 --- a/zk-token-sdk/src/instruction/transfer.rs +++ b/zk-token-sdk/src/instruction/transfer.rs @@ -24,7 +24,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/transfer_with_fee.rs b/zk-token-sdk/src/instruction/transfer_with_fee.rs index 213d9356f24388..614bc7d2e54b50 100644 --- a/zk-token-sdk/src/instruction/transfer_with_fee.rs +++ b/zk-token-sdk/src/instruction/transfer_with_fee.rs @@ -29,7 +29,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/withdraw.rs b/zk-token-sdk/src/instruction/withdraw.rs index 2ddd1462b0dbf6..9bb674562d60df 100644 --- a/zk-token-sdk/src/instruction/withdraw.rs +++ b/zk-token-sdk/src/instruction/withdraw.rs @@ -16,7 +16,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/zero_balance.rs b/zk-token-sdk/src/instruction/zero_balance.rs index 672ada7d9b6890..5c34676a56f97f 100644 --- a/zk-token-sdk/src/instruction/zero_balance.rs +++ b/zk-token-sdk/src/instruction/zero_balance.rs @@ -18,7 +18,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - zk_token_elgamal::pod, + pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/lib.rs b/zk-token-sdk/src/lib.rs index 14ce5b4380af47..23c4612c6ec758 100644 --- a/zk-token-sdk/src/lib.rs +++ b/zk-token-sdk/src/lib.rs @@ -34,7 +34,7 @@ mod transcript; // TODO: re-organize visibility pub mod curve25519; pub mod instruction; -pub mod zk_token_elgamal; +pub mod pod; pub mod zk_token_proof_instruction; pub mod zk_token_proof_program; pub mod zk_token_proof_state; diff --git a/zk-token-sdk/src/zk_token_elgamal/convert.rs b/zk-token-sdk/src/pod/convert.rs similarity index 100% rename from zk-token-sdk/src/zk_token_elgamal/convert.rs rename to zk-token-sdk/src/pod/convert.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/decryption.rs b/zk-token-sdk/src/pod/decryption.rs similarity index 100% rename from zk-token-sdk/src/zk_token_elgamal/decryption.rs rename to zk-token-sdk/src/pod/decryption.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/elgamal.rs b/zk-token-sdk/src/pod/elgamal.rs similarity index 98% rename from zk-token-sdk/src/zk_token_elgamal/elgamal.rs rename to zk-token-sdk/src/pod/elgamal.rs index e3691bd744bab1..d593c5095ef1f0 100644 --- a/zk-token-sdk/src/zk_token_elgamal/elgamal.rs +++ b/zk-token-sdk/src/pod/elgamal.rs @@ -2,7 +2,7 @@ use { crate::{ encryption::elgamal, errors::ProofError, - zk_token_elgamal::{Pod, Zeroable}, + pod::{Pod, Zeroable}, }, base64::{prelude::BASE64_STANDARD, Engine}, curve25519_dalek::ristretto::CompressedRistretto, diff --git a/zk-token-sdk/src/zk_token_elgamal/mod.rs b/zk-token-sdk/src/pod/mod.rs similarity index 100% rename from zk-token-sdk/src/zk_token_elgamal/mod.rs rename to zk-token-sdk/src/pod/mod.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/ops.rs b/zk-token-sdk/src/pod/ops.rs similarity index 100% rename from zk-token-sdk/src/zk_token_elgamal/ops.rs rename to zk-token-sdk/src/pod/ops.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/pedersen.rs b/zk-token-sdk/src/pod/pedersen.rs similarity index 96% rename from zk-token-sdk/src/zk_token_elgamal/pedersen.rs rename to zk-token-sdk/src/pod/pedersen.rs index 6d76f6ac834f00..8448853b2a775e 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pedersen.rs +++ b/zk-token-sdk/src/pod/pedersen.rs @@ -2,7 +2,7 @@ use { crate::{ encryption::pedersen, errors::ProofError, - zk_token_elgamal::{Pod, Zeroable}, + pod::{Pod, Zeroable}, }, curve25519_dalek::ristretto::CompressedRistretto, std::fmt, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod.rs b/zk-token-sdk/src/pod/pod.rs similarity index 98% rename from zk-token-sdk/src/zk_token_elgamal/pod.rs rename to zk-token-sdk/src/pod/pod.rs index 97c5dcb07542cd..c6bf0ef41f84a4 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod.rs +++ b/zk-token-sdk/src/pod/pod.rs @@ -1,6 +1,6 @@ pub use bytemuck::{Pod, Zeroable}; use { - crate::zk_token_elgamal::{elgamal::*, pedersen::*, PodU16, PodU64}, + crate::pod::{elgamal::*, pedersen::*, PodU16, PodU64}, base64::{prelude::BASE64_STANDARD, Engine}, std::fmt, }; diff --git a/zk-token-sdk/src/transcript.rs b/zk-token-sdk/src/transcript.rs index c0ed1161666c9e..a4e14e300dbc7e 100644 --- a/zk-token-sdk/src/transcript.rs +++ b/zk-token-sdk/src/transcript.rs @@ -1,5 +1,5 @@ use { - crate::{errors::TranscriptError, zk_token_elgamal::pod}, + crate::{errors::TranscriptError, pod}, curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar, traits::IsIdentity}, merlin::Transcript, }; diff --git a/zk-token-sdk/src/zk_token_proof_state.rs b/zk-token-sdk/src/zk_token_proof_state.rs index 6fc2e0b663e25d..9651dd299872a7 100644 --- a/zk-token-sdk/src/zk_token_proof_state.rs +++ b/zk-token-sdk/src/zk_token_proof_state.rs @@ -1,5 +1,5 @@ use { - crate::{zk_token_elgamal::PodProofType, zk_token_proof_instruction::ProofType}, + crate::{pod::PodProofType, zk_token_proof_instruction::ProofType}, bytemuck::{bytes_of, Pod, Zeroable}, num_traits::ToPrimitive, solana_program::{ From 2041c2671bb9fe90f4488f82352a3007eb93107a Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 16:29:59 +0900 Subject: [PATCH 04/11] refactor pod `AeCiphertext` into a separate submodule --- zk-token-sdk/src/pod/auth_encryption.rs | 53 +++++++++++++++++++++++++ zk-token-sdk/src/pod/convert.rs | 14 ------- zk-token-sdk/src/pod/mod.rs | 1 + zk-token-sdk/src/pod/pod.rs | 28 ------------- 4 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 zk-token-sdk/src/pod/auth_encryption.rs diff --git a/zk-token-sdk/src/pod/auth_encryption.rs b/zk-token-sdk/src/pod/auth_encryption.rs new file mode 100644 index 00000000000000..ef6086f3f0b964 --- /dev/null +++ b/zk-token-sdk/src/pod/auth_encryption.rs @@ -0,0 +1,53 @@ +use { + crate::{ + encryption::auth_encryption, + errors::ProofError, + pod::{Pod, Zeroable}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + std::fmt, +}; + +/// 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() + } +} + +#[cfg(not(target_os = "solana"))] +impl From for AeCiphertext { + fn from(ct: auth_encryption::AeCiphertext) -> Self { + Self(ct.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for auth_encryption::AeCiphertext { + type Error = ProofError; + + fn try_from(ct: AeCiphertext) -> Result { + Self::from_bytes(&ct.0).ok_or(ProofError::CiphertextDeserialization) + } +} diff --git a/zk-token-sdk/src/pod/convert.rs b/zk-token-sdk/src/pod/convert.rs index 2f9db2f1540275..9910723f9d67d6 100644 --- a/zk-token-sdk/src/pod/convert.rs +++ b/zk-token-sdk/src/pod/convert.rs @@ -99,20 +99,6 @@ mod target_arch { } } - impl From for pod::AeCiphertext { - fn from(ct: AeCiphertext) -> Self { - Self(ct.to_bytes()) - } - } - - impl TryFrom for AeCiphertext { - type Error = ProofError; - - fn try_from(ct: pod::AeCiphertext) -> Result { - Self::from_bytes(&ct.0).ok_or(ProofError::CiphertextDeserialization) - } - } - impl From for pod::CiphertextCommitmentEqualityProof { fn from(proof: CiphertextCommitmentEqualityProof) -> Self { Self(proof.to_bytes()) diff --git a/zk-token-sdk/src/pod/mod.rs b/zk-token-sdk/src/pod/mod.rs index 52b241c6288d57..ba89e8c9a62c65 100644 --- a/zk-token-sdk/src/pod/mod.rs +++ b/zk-token-sdk/src/pod/mod.rs @@ -2,6 +2,7 @@ pub mod convert; // pub mod decryption; pub mod elgamal; // pub mod ops; +pub mod auth_encryption; pub mod pedersen; pub mod pod; diff --git a/zk-token-sdk/src/pod/pod.rs b/zk-token-sdk/src/pod/pod.rs index c6bf0ef41f84a4..8eecefa680d889 100644 --- a/zk-token-sdk/src/pod/pod.rs +++ b/zk-token-sdk/src/pod/pod.rs @@ -99,34 +99,6 @@ pub struct RangeProof256(pub [u8; 800]); 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)] From 2a433321f20c2b842ad17e220488c08913c87faf Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 16:55:46 +0900 Subject: [PATCH 05/11] refactor range proof and sigma proof pod types into separate submodules --- zk-token-sdk/src/pod/convert.rs | 191 +-------------------------- zk-token-sdk/src/pod/mod.rs | 9 ++ zk-token-sdk/src/pod/pod.rs | 96 +------------- zk-token-sdk/src/pod/range_proof.rs | 128 ++++++++++++++++++ zk-token-sdk/src/pod/sigma_proofs.rs | 187 ++++++++++++++++++++++++++ 5 files changed, 326 insertions(+), 285 deletions(-) create mode 100644 zk-token-sdk/src/pod/range_proof.rs create mode 100644 zk-token-sdk/src/pod/sigma_proofs.rs diff --git a/zk-token-sdk/src/pod/convert.rs b/zk-token-sdk/src/pod/convert.rs index 9910723f9d67d6..8e625fd48c8ad2 100644 --- a/zk-token-sdk/src/pod/convert.rs +++ b/zk-token-sdk/src/pod/convert.rs @@ -52,13 +52,11 @@ mod target_arch { super::pod, crate::{ curve25519::scalar::PodScalar, - encryption::auth_encryption::AeCiphertext, - errors::{ProofError, ProofVerificationError}, + errors::ProofError, instruction::{ transfer::{TransferAmountEncryption, TransferPubkeys}, transfer_with_fee::{FeeEncryption, FeeParameters, TransferWithFeePubkeys}, }, - range_proof::{errors::RangeProofError, RangeProof}, sigma_proofs::{ ctxt_comm_equality_proof::CiphertextCommitmentEqualityProof, ctxt_ctxt_equality_proof::CiphertextCiphertextEqualityProof, @@ -99,193 +97,6 @@ mod target_arch { } } - impl From for pod::CiphertextCommitmentEqualityProof { - fn from(proof: CiphertextCommitmentEqualityProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for CiphertextCommitmentEqualityProof { - type Error = EqualityProofError; - - fn try_from(pod: pod::CiphertextCommitmentEqualityProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::CiphertextCiphertextEqualityProof { - fn from(proof: CiphertextCiphertextEqualityProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for CiphertextCiphertextEqualityProof { - type Error = EqualityProofError; - - fn try_from(pod: pod::CiphertextCiphertextEqualityProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::ValidityProof { - fn from(proof: ValidityProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for ValidityProof { - type Error = ValidityProofError; - - fn try_from(pod: pod::ValidityProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::AggregatedValidityProof { - fn from(proof: AggregatedValidityProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for AggregatedValidityProof { - type Error = ValidityProofError; - - fn try_from(pod: pod::AggregatedValidityProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::ZeroBalanceProof { - fn from(proof: ZeroBalanceProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for ZeroBalanceProof { - type Error = ZeroBalanceProofError; - - fn try_from(pod: pod::ZeroBalanceProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::FeeSigmaProof { - fn from(proof: FeeSigmaProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for FeeSigmaProof { - type Error = FeeSigmaProofError; - - fn try_from(pod: pod::FeeSigmaProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl From for pod::PubkeyValidityProof { - fn from(proof: PubkeyValidityProof) -> Self { - Self(proof.to_bytes()) - } - } - - impl TryFrom for PubkeyValidityProof { - type Error = PubkeyValidityProofError; - - fn try_from(pod: pod::PubkeyValidityProof) -> Result { - Self::from_bytes(&pod.0) - } - } - - impl TryFrom for pod::RangeProof64 { - type Error = RangeProofError; - - fn try_from(proof: RangeProof) -> Result { - if proof.ipp_proof.serialized_size() != 448 { - return Err(ProofVerificationError::Deserialization.into()); - } - - let mut buf = [0_u8; 672]; - buf[..32].copy_from_slice(proof.A.as_bytes()); - buf[32..64].copy_from_slice(proof.S.as_bytes()); - buf[64..96].copy_from_slice(proof.T_1.as_bytes()); - buf[96..128].copy_from_slice(proof.T_2.as_bytes()); - buf[128..160].copy_from_slice(proof.t_x.as_bytes()); - buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); - buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); - buf[224..672].copy_from_slice(&proof.ipp_proof.to_bytes()); - Ok(pod::RangeProof64(buf)) - } - } - - impl TryFrom for RangeProof { - type Error = RangeProofError; - - fn try_from(pod: pod::RangeProof64) -> Result { - Self::from_bytes(&pod.0) - } - } - - #[cfg(not(target_os = "solana"))] - impl TryFrom for pod::RangeProof128 { - type Error = RangeProofError; - - fn try_from(proof: RangeProof) -> Result { - if proof.ipp_proof.serialized_size() != 512 { - return Err(ProofVerificationError::Deserialization.into()); - } - - let mut buf = [0_u8; 736]; - buf[..32].copy_from_slice(proof.A.as_bytes()); - buf[32..64].copy_from_slice(proof.S.as_bytes()); - buf[64..96].copy_from_slice(proof.T_1.as_bytes()); - buf[96..128].copy_from_slice(proof.T_2.as_bytes()); - buf[128..160].copy_from_slice(proof.t_x.as_bytes()); - buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); - buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); - buf[224..736].copy_from_slice(&proof.ipp_proof.to_bytes()); - Ok(pod::RangeProof128(buf)) - } - } - - impl TryFrom for RangeProof { - type Error = RangeProofError; - - fn try_from(pod: pod::RangeProof128) -> Result { - Self::from_bytes(&pod.0) - } - } - - #[cfg(not(target_os = "solana"))] - impl TryFrom for pod::RangeProof256 { - type Error = RangeProofError; - - fn try_from(proof: RangeProof) -> Result { - if proof.ipp_proof.serialized_size() != 576 { - return Err(ProofVerificationError::Deserialization.into()); - } - - let mut buf = [0_u8; 800]; - buf[..32].copy_from_slice(proof.A.as_bytes()); - buf[32..64].copy_from_slice(proof.S.as_bytes()); - buf[64..96].copy_from_slice(proof.T_1.as_bytes()); - buf[96..128].copy_from_slice(proof.T_2.as_bytes()); - buf[128..160].copy_from_slice(proof.t_x.as_bytes()); - buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); - buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); - buf[224..800].copy_from_slice(&proof.ipp_proof.to_bytes()); - Ok(pod::RangeProof256(buf)) - } - } - - impl TryFrom for RangeProof { - type Error = RangeProofError; - - fn try_from(pod: pod::RangeProof256) -> Result { - Self::from_bytes(&pod.0) - } - } - impl From for pod::TransferPubkeys { fn from(keys: TransferPubkeys) -> Self { Self { diff --git a/zk-token-sdk/src/pod/mod.rs b/zk-token-sdk/src/pod/mod.rs index ba89e8c9a62c65..ed47f3b8a5de6b 100644 --- a/zk-token-sdk/src/pod/mod.rs +++ b/zk-token-sdk/src/pod/mod.rs @@ -5,6 +5,8 @@ pub mod elgamal; pub mod auth_encryption; pub mod pedersen; pub mod pod; +pub mod range_proof; +pub mod sigma_proofs; use { crate::zk_token_proof_instruction::ProofType, @@ -13,9 +15,16 @@ use { }; pub use { + auth_encryption::AeCiphertext, bytemuck::{Pod, Zeroable}, elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, pedersen::PedersenCommitment, + range_proof::{RangeProof128, RangeProof256, RangeProof64}, + sigma_proofs::{ + AggregatedValidityProof, CiphertextCiphertextEqualityProof, + CiphertextCommitmentEqualityProof, FeeSigmaProof, PubkeyValidityProof, ValidityProof, + ZeroBalanceProof, + }, }; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] diff --git a/zk-token-sdk/src/pod/pod.rs b/zk-token-sdk/src/pod/pod.rs index 8eecefa680d889..ce033400ffb859 100644 --- a/zk-token-sdk/src/pod/pod.rs +++ b/zk-token-sdk/src/pod/pod.rs @@ -1,104 +1,10 @@ +use crate::pod::{elgamal::*, pedersen::*, PodU16, PodU64}; pub use bytemuck::{Pod, Zeroable}; -use { - crate::pod::{elgamal::*, pedersen::*, PodU16, PodU64}, - base64::{prelude::BASE64_STANDARD, Engine}, - std::fmt, -}; #[derive(Clone, Copy, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct CompressedRistretto(pub [u8; 32]); -/// Serialization of `CiphertextCommitmentEqualityProof` -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct CiphertextCommitmentEqualityProof(pub [u8; 192]); - -// `CiphertextCommitmentEqualityProof` is a Pod and Zeroable. -// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays -unsafe impl Zeroable for CiphertextCommitmentEqualityProof {} -unsafe impl Pod for CiphertextCommitmentEqualityProof {} - -/// Serialization of `CtxtCtxtEqualityProof` -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct CiphertextCiphertextEqualityProof(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 CiphertextCiphertextEqualityProof {} -unsafe impl Pod for CiphertextCiphertextEqualityProof {} - -/// 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 PubkeyValidityProof(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 {} - // TODO: refactor this code into the instruction module #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] diff --git a/zk-token-sdk/src/pod/range_proof.rs b/zk-token-sdk/src/pod/range_proof.rs new file mode 100644 index 00000000000000..944f5a794645ab --- /dev/null +++ b/zk-token-sdk/src/pod/range_proof.rs @@ -0,0 +1,128 @@ +use crate::{ + errors::ProofVerificationError, + pod::{Pod, Zeroable}, + range_proof::{self, errors::RangeProofError}, +}; + +/// 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 {} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof64 { + type Error = RangeProofError; + + fn try_from(proof: range_proof::RangeProof) -> Result { + if proof.ipp_proof.serialized_size() != 448 { + return Err(ProofVerificationError::Deserialization.into()); + } + + let mut buf = [0_u8; 672]; + buf[..32].copy_from_slice(proof.A.as_bytes()); + buf[32..64].copy_from_slice(proof.S.as_bytes()); + buf[64..96].copy_from_slice(proof.T_1.as_bytes()); + buf[96..128].copy_from_slice(proof.T_2.as_bytes()); + buf[128..160].copy_from_slice(proof.t_x.as_bytes()); + buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); + buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); + buf[224..672].copy_from_slice(&proof.ipp_proof.to_bytes()); + Ok(RangeProof64(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for range_proof::RangeProof { + type Error = RangeProofError; + + fn try_from(pod: RangeProof64) -> Result { + Self::from_bytes(&pod.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof128 { + type Error = RangeProofError; + + fn try_from(proof: range_proof::RangeProof) -> Result { + if proof.ipp_proof.serialized_size() != 512 { + return Err(ProofVerificationError::Deserialization.into()); + } + + let mut buf = [0_u8; 736]; + buf[..32].copy_from_slice(proof.A.as_bytes()); + buf[32..64].copy_from_slice(proof.S.as_bytes()); + buf[64..96].copy_from_slice(proof.T_1.as_bytes()); + buf[96..128].copy_from_slice(proof.T_2.as_bytes()); + buf[128..160].copy_from_slice(proof.t_x.as_bytes()); + buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); + buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); + buf[224..736].copy_from_slice(&proof.ipp_proof.to_bytes()); + Ok(RangeProof128(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for range_proof::RangeProof { + type Error = RangeProofError; + + fn try_from(pod: RangeProof128) -> Result { + Self::from_bytes(&pod.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof256 { + type Error = RangeProofError; + + fn try_from(proof: range_proof::RangeProof) -> Result { + if proof.ipp_proof.serialized_size() != 576 { + return Err(ProofVerificationError::Deserialization.into()); + } + + let mut buf = [0_u8; 800]; + buf[..32].copy_from_slice(proof.A.as_bytes()); + buf[32..64].copy_from_slice(proof.S.as_bytes()); + buf[64..96].copy_from_slice(proof.T_1.as_bytes()); + buf[96..128].copy_from_slice(proof.T_2.as_bytes()); + buf[128..160].copy_from_slice(proof.t_x.as_bytes()); + buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes()); + buf[192..224].copy_from_slice(proof.e_blinding.as_bytes()); + buf[224..800].copy_from_slice(&proof.ipp_proof.to_bytes()); + Ok(RangeProof256(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for range_proof::RangeProof { + type Error = RangeProofError; + + fn try_from(pod: RangeProof256) -> Result { + Self::from_bytes(&pod.0) + } +} diff --git a/zk-token-sdk/src/pod/sigma_proofs.rs b/zk-token-sdk/src/pod/sigma_proofs.rs new file mode 100644 index 00000000000000..2f00a435aba0c1 --- /dev/null +++ b/zk-token-sdk/src/pod/sigma_proofs.rs @@ -0,0 +1,187 @@ +use crate::{ + pod::{Pod, Zeroable}, + sigma_proofs::{ + ctxt_comm_equality_proof, ctxt_ctxt_equality_proof, errors::*, fee_proof, pubkey_proof, + validity_proof, zero_balance_proof, + }, +}; + +/// Serialization of `CiphertextCommitmentEqualityProof` +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct CiphertextCommitmentEqualityProof(pub [u8; 192]); + +// `CiphertextCommitmentEqualityProof` is a Pod and Zeroable. +// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays +unsafe impl Zeroable for CiphertextCommitmentEqualityProof {} +unsafe impl Pod for CiphertextCommitmentEqualityProof {} + +#[cfg(not(target_os = "solana"))] +impl From + for CiphertextCommitmentEqualityProof +{ + fn from(proof: ctxt_comm_equality_proof::CiphertextCommitmentEqualityProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom + for ctxt_comm_equality_proof::CiphertextCommitmentEqualityProof +{ + type Error = EqualityProofError; + + fn try_from(pod: CiphertextCommitmentEqualityProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// Serialization of `CtxtCtxtEqualityProof` +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct CiphertextCiphertextEqualityProof(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 CiphertextCiphertextEqualityProof {} +unsafe impl Pod for CiphertextCiphertextEqualityProof {} + +#[cfg(not(target_os = "solana"))] +impl From + for CiphertextCiphertextEqualityProof +{ + fn from(proof: ctxt_ctxt_equality_proof::CiphertextCiphertextEqualityProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom + for ctxt_ctxt_equality_proof::CiphertextCiphertextEqualityProof +{ + type Error = EqualityProofError; + + fn try_from(pod: CiphertextCiphertextEqualityProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// 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 {} + +#[cfg(not(target_os = "solana"))] +impl From for ValidityProof { + fn from(proof: validity_proof::ValidityProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for validity_proof::ValidityProof { + type Error = ValidityProofError; + + fn try_from(pod: ValidityProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// 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 {} + +#[cfg(not(target_os = "solana"))] +impl From for AggregatedValidityProof { + fn from(proof: validity_proof::AggregatedValidityProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for validity_proof::AggregatedValidityProof { + type Error = ValidityProofError; + + fn try_from(pod: AggregatedValidityProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// 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 {} + +#[cfg(not(target_os = "solana"))] +impl From for ZeroBalanceProof { + fn from(proof: zero_balance_proof::ZeroBalanceProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for zero_balance_proof::ZeroBalanceProof { + type Error = ZeroBalanceProofError; + + fn try_from(pod: ZeroBalanceProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// Serialization of fee sigma proof +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(transparent)] +pub struct FeeSigmaProof(pub [u8; 256]); + +#[cfg(not(target_os = "solana"))] +impl From for FeeSigmaProof { + fn from(proof: fee_proof::FeeSigmaProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for fee_proof::FeeSigmaProof { + type Error = FeeSigmaProofError; + + fn try_from(pod: FeeSigmaProof) -> Result { + Self::from_bytes(&pod.0) + } +} + +/// Serialization of public-key sigma proof +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(transparent)] +pub struct PubkeyValidityProof(pub [u8; 64]); + +#[cfg(not(target_os = "solana"))] +impl From for PubkeyValidityProof { + fn from(proof: pubkey_proof::PubkeyValidityProof) -> Self { + Self(proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for pubkey_proof::PubkeyValidityProof { + type Error = PubkeyValidityProofError; + + fn try_from(pod: PubkeyValidityProof) -> Result { + Self::from_bytes(&pod.0) + } +} From f8f63488bf39a05d090d7a98cce31d729f0ce283 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 17:10:18 +0900 Subject: [PATCH 06/11] refactor instruction pod types into a separate submodule --- zk-token-sdk/src/pod/convert.rs | 125 -------------------- zk-token-sdk/src/pod/instruction.rs | 174 ++++++++++++++++++++++++++++ zk-token-sdk/src/pod/mod.rs | 11 +- zk-token-sdk/src/pod/pod.rs | 44 ------- 4 files changed, 180 insertions(+), 174 deletions(-) create mode 100644 zk-token-sdk/src/pod/instruction.rs diff --git a/zk-token-sdk/src/pod/convert.rs b/zk-token-sdk/src/pod/convert.rs index 8e625fd48c8ad2..63aae9bb104cca 100644 --- a/zk-token-sdk/src/pod/convert.rs +++ b/zk-token-sdk/src/pod/convert.rs @@ -57,15 +57,6 @@ mod target_arch { transfer::{TransferAmountEncryption, TransferPubkeys}, transfer_with_fee::{FeeEncryption, FeeParameters, TransferWithFeePubkeys}, }, - sigma_proofs::{ - ctxt_comm_equality_proof::CiphertextCommitmentEqualityProof, - ctxt_ctxt_equality_proof::CiphertextCiphertextEqualityProof, - errors::*, - fee_proof::FeeSigmaProof, - pubkey_proof::PubkeyValidityProof, - validity_proof::{AggregatedValidityProof, ValidityProof}, - zero_balance_proof::ZeroBalanceProof, - }, }, curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar}, std::convert::TryFrom, @@ -96,122 +87,6 @@ mod target_arch { Self(pod.0) } } - - impl From for pod::TransferPubkeys { - fn from(keys: TransferPubkeys) -> Self { - Self { - source_pubkey: keys.source_pubkey.into(), - destination_pubkey: keys.destination_pubkey.into(), - auditor_pubkey: keys.auditor_pubkey.into(), - } - } - } - - impl TryFrom for TransferPubkeys { - type Error = ProofError; - - fn try_from(pod: pod::TransferPubkeys) -> Result { - Ok(Self { - source_pubkey: pod.source_pubkey.try_into()?, - destination_pubkey: pod.destination_pubkey.try_into()?, - auditor_pubkey: pod.auditor_pubkey.try_into()?, - }) - } - } - - impl From for pod::TransferWithFeePubkeys { - fn from(keys: TransferWithFeePubkeys) -> Self { - Self { - source_pubkey: keys.source_pubkey.into(), - destination_pubkey: keys.destination_pubkey.into(), - auditor_pubkey: keys.auditor_pubkey.into(), - withdraw_withheld_authority_pubkey: keys.withdraw_withheld_authority_pubkey.into(), - } - } - } - - impl TryFrom for TransferWithFeePubkeys { - type Error = ProofError; - - fn try_from(pod: pod::TransferWithFeePubkeys) -> Result { - Ok(Self { - source_pubkey: pod.source_pubkey.try_into()?, - destination_pubkey: pod.destination_pubkey.try_into()?, - auditor_pubkey: pod.auditor_pubkey.try_into()?, - withdraw_withheld_authority_pubkey: pod - .withdraw_withheld_authority_pubkey - .try_into()?, - }) - } - } - - impl From for pod::TransferAmountEncryption { - fn from(ciphertext: TransferAmountEncryption) -> Self { - Self { - commitment: ciphertext.commitment.into(), - source_handle: ciphertext.source_handle.into(), - destination_handle: ciphertext.destination_handle.into(), - auditor_handle: ciphertext.auditor_handle.into(), - } - } - } - - impl TryFrom for TransferAmountEncryption { - type Error = ProofError; - - fn try_from(pod: pod::TransferAmountEncryption) -> Result { - Ok(Self { - commitment: pod.commitment.try_into()?, - source_handle: pod.source_handle.try_into()?, - destination_handle: pod.destination_handle.try_into()?, - auditor_handle: pod.auditor_handle.try_into()?, - }) - } - } - - impl From for pod::FeeEncryption { - fn from(ciphertext: FeeEncryption) -> Self { - Self { - commitment: ciphertext.commitment.into(), - destination_handle: ciphertext.destination_handle.into(), - withdraw_withheld_authority_handle: ciphertext - .withdraw_withheld_authority_handle - .into(), - } - } - } - - impl TryFrom for FeeEncryption { - type Error = ProofError; - - fn try_from(pod: pod::FeeEncryption) -> Result { - Ok(Self { - commitment: pod.commitment.try_into()?, - destination_handle: pod.destination_handle.try_into()?, - withdraw_withheld_authority_handle: pod - .withdraw_withheld_authority_handle - .try_into()?, - }) - } - } - - impl From for pod::FeeParameters { - fn from(parameters: FeeParameters) -> Self { - Self { - fee_rate_basis_points: parameters.fee_rate_basis_points.into(), - maximum_fee: parameters.maximum_fee.into(), - } - } - } - - impl From for FeeParameters { - fn from(pod: pod::FeeParameters) -> Self { - Self { - fee_rate_basis_points: pod.fee_rate_basis_points.into(), - maximum_fee: pod.maximum_fee.into(), - } - } - } } #[cfg(target_os = "solana")] diff --git a/zk-token-sdk/src/pod/instruction.rs b/zk-token-sdk/src/pod/instruction.rs new file mode 100644 index 00000000000000..013357c5e8d060 --- /dev/null +++ b/zk-token-sdk/src/pod/instruction.rs @@ -0,0 +1,174 @@ +use crate::{ + errors::ProofError, + instruction::{transfer, transfer_with_fee}, + pod::{elgamal::*, pedersen::*, Pod, PodU16, PodU64, Zeroable}, +}; + +#[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, +} + +#[cfg(not(target_os = "solana"))] +impl From for TransferPubkeys { + fn from(keys: transfer::TransferPubkeys) -> Self { + Self { + source_pubkey: keys.source_pubkey.into(), + destination_pubkey: keys.destination_pubkey.into(), + auditor_pubkey: keys.auditor_pubkey.into(), + } + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for transfer::TransferPubkeys { + type Error = ProofError; + + fn try_from(pod: TransferPubkeys) -> Result { + Ok(Self { + source_pubkey: pod.source_pubkey.try_into()?, + destination_pubkey: pod.destination_pubkey.try_into()?, + auditor_pubkey: pod.auditor_pubkey.try_into()?, + }) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for TransferWithFeePubkeys { + fn from(keys: transfer_with_fee::TransferWithFeePubkeys) -> Self { + Self { + source_pubkey: keys.source_pubkey.into(), + destination_pubkey: keys.destination_pubkey.into(), + auditor_pubkey: keys.auditor_pubkey.into(), + withdraw_withheld_authority_pubkey: keys.withdraw_withheld_authority_pubkey.into(), + } + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for transfer_with_fee::TransferWithFeePubkeys { + type Error = ProofError; + + fn try_from(pod: TransferWithFeePubkeys) -> Result { + Ok(Self { + source_pubkey: pod.source_pubkey.try_into()?, + destination_pubkey: pod.destination_pubkey.try_into()?, + auditor_pubkey: pod.auditor_pubkey.try_into()?, + withdraw_withheld_authority_pubkey: pod + .withdraw_withheld_authority_pubkey + .try_into()?, + }) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for TransferAmountEncryption { + fn from(ciphertext: transfer::TransferAmountEncryption) -> Self { + Self { + commitment: ciphertext.commitment.into(), + source_handle: ciphertext.source_handle.into(), + destination_handle: ciphertext.destination_handle.into(), + auditor_handle: ciphertext.auditor_handle.into(), + } + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for transfer::TransferAmountEncryption { + type Error = ProofError; + + fn try_from(pod: TransferAmountEncryption) -> Result { + Ok(Self { + commitment: pod.commitment.try_into()?, + source_handle: pod.source_handle.try_into()?, + destination_handle: pod.destination_handle.try_into()?, + auditor_handle: pod.auditor_handle.try_into()?, + }) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for FeeEncryption { + fn from(ciphertext: transfer_with_fee::FeeEncryption) -> Self { + Self { + commitment: ciphertext.commitment.into(), + destination_handle: ciphertext.destination_handle.into(), + withdraw_withheld_authority_handle: ciphertext + .withdraw_withheld_authority_handle + .into(), + } + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for transfer_with_fee::FeeEncryption { + type Error = ProofError; + + fn try_from(pod: FeeEncryption) -> Result { + Ok(Self { + commitment: pod.commitment.try_into()?, + destination_handle: pod.destination_handle.try_into()?, + withdraw_withheld_authority_handle: pod + .withdraw_withheld_authority_handle + .try_into()?, + }) + } +} + +#[cfg(not(target_os = "solana"))] +impl From for FeeParameters { + fn from(parameters: transfer_with_fee::FeeParameters) -> Self { + Self { + fee_rate_basis_points: parameters.fee_rate_basis_points.into(), + maximum_fee: parameters.maximum_fee.into(), + } + } +} + +#[cfg(not(target_os = "solana"))] +impl From for transfer_with_fee::FeeParameters { + fn from(pod: FeeParameters) -> Self { + Self { + fee_rate_basis_points: pod.fee_rate_basis_points.into(), + maximum_fee: pod.maximum_fee.into(), + } + } +} diff --git a/zk-token-sdk/src/pod/mod.rs b/zk-token-sdk/src/pod/mod.rs index ed47f3b8a5de6b..a011f3ff9ecfa8 100644 --- a/zk-token-sdk/src/pod/mod.rs +++ b/zk-token-sdk/src/pod/mod.rs @@ -1,10 +1,7 @@ -pub mod convert; -// pub mod decryption; -pub mod elgamal; -// pub mod ops; pub mod auth_encryption; +pub mod elgamal; +pub mod instruction; pub mod pedersen; -pub mod pod; pub mod range_proof; pub mod sigma_proofs; @@ -18,6 +15,10 @@ pub use { auth_encryption::AeCiphertext, bytemuck::{Pod, Zeroable}, elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, + instruction::{ + FeeEncryption, FeeParameters, TransferAmountEncryption, TransferPubkeys, + TransferWithFeePubkeys, + }, pedersen::PedersenCommitment, range_proof::{RangeProof128, RangeProof256, RangeProof64}, sigma_proofs::{ diff --git a/zk-token-sdk/src/pod/pod.rs b/zk-token-sdk/src/pod/pod.rs index ce033400ffb859..ba84b492fee86d 100644 --- a/zk-token-sdk/src/pod/pod.rs +++ b/zk-token-sdk/src/pod/pod.rs @@ -4,47 +4,3 @@ pub use bytemuck::{Pod, Zeroable}; #[derive(Clone, Copy, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct CompressedRistretto(pub [u8; 32]); - -// 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, -} From cfde950565e3a195531d376c35a5ca000ebaa57c Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 17:46:43 +0900 Subject: [PATCH 07/11] refactor pod ops --- zk-token-sdk/src/pod/convert.rs | 45 -------------------------------- zk-token-sdk/src/pod/elgamal.rs | 33 ++++++++++++++++++++++- zk-token-sdk/src/pod/mod.rs | 1 + zk-token-sdk/src/pod/ops.rs | 4 +-- zk-token-sdk/src/pod/pedersen.rs | 13 +++++++++ 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/zk-token-sdk/src/pod/convert.rs b/zk-token-sdk/src/pod/convert.rs index 63aae9bb104cca..e85e56e99c0949 100644 --- a/zk-token-sdk/src/pod/convert.rs +++ b/zk-token-sdk/src/pod/convert.rs @@ -1,51 +1,6 @@ pub use target_arch::*; use {super::pod, crate::curve25519::ristretto::PodRistrettoPoint}; -// impl From<(pod::PedersenCommitment, pod::DecryptHandle)> for pod::ElGamalCiphertext { -// fn from((commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle)) -> Self { -// let mut buf = [0_u8; 64]; -// buf[..32].copy_from_slice(&commitment.0); -// buf[32..].copy_from_slice(&handle.0); -// pod::ElGamalCiphertext(buf) -// } -// } - -// impl From for (pod::PedersenCommitment, pod::DecryptHandle) { -// fn from(ciphertext: pod::ElGamalCiphertext) -> Self { -// let commitment: [u8; 32] = ciphertext.0[..32].try_into().unwrap(); -// let handle: [u8; 32] = ciphertext.0[32..].try_into().unwrap(); - -// ( -// pod::PedersenCommitment(commitment), -// pod::DecryptHandle(handle), -// ) -// } -// } - -// impl From for PodRistrettoPoint { -// fn from(commitment: pod::PedersenCommitment) -> Self { -// PodRistrettoPoint(commitment.0) -// } -// } - -// impl From for pod::PedersenCommitment { -// fn from(point: PodRistrettoPoint) -> Self { -// pod::PedersenCommitment(point.0) -// } -// } - -// impl From for PodRistrettoPoint { -// fn from(handle: pod::DecryptHandle) -> Self { -// PodRistrettoPoint(handle.0) -// } -// } - -// impl From for pod::DecryptHandle { -// fn from(point: PodRistrettoPoint) -> Self { -// pod::DecryptHandle(point.0) -// } -// } - #[cfg(not(target_os = "solana"))] mod target_arch { use { diff --git a/zk-token-sdk/src/pod/elgamal.rs b/zk-token-sdk/src/pod/elgamal.rs index d593c5095ef1f0..8d6ab8f96b6255 100644 --- a/zk-token-sdk/src/pod/elgamal.rs +++ b/zk-token-sdk/src/pod/elgamal.rs @@ -1,8 +1,9 @@ use { crate::{ + curve25519::ristretto::PodRistrettoPoint, encryption::elgamal, errors::ProofError, - pod::{Pod, Zeroable}, + pod::{pedersen::PedersenCommitment, Pod, Zeroable}, }, base64::{prelude::BASE64_STANDARD, Engine}, curve25519_dalek::ristretto::CompressedRistretto, @@ -79,6 +80,24 @@ impl TryFrom for elgamal::ElGamalCiphertext { } } +impl From<(PedersenCommitment, DecryptHandle)> for ElGamalCiphertext { + fn from((commitment, handle): (PedersenCommitment, DecryptHandle)) -> Self { + let mut buf = [0_u8; 64]; + buf[..32].copy_from_slice(&commitment.0); + buf[32..].copy_from_slice(&handle.0); + ElGamalCiphertext(buf) + } +} + +impl From for (PedersenCommitment, DecryptHandle) { + fn from(ciphertext: ElGamalCiphertext) -> Self { + let commitment: [u8; 32] = ciphertext.0[..32].try_into().unwrap(); + let handle: [u8; 32] = ciphertext.0[32..].try_into().unwrap(); + + (PedersenCommitment(commitment), DecryptHandle(handle)) + } +} + #[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct DecryptHandle(pub [u8; 32]); @@ -112,3 +131,15 @@ impl TryFrom for elgamal::DecryptHandle { Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) } } + +impl From for PodRistrettoPoint { + fn from(handle: DecryptHandle) -> Self { + PodRistrettoPoint(handle.0) + } +} + +impl From for DecryptHandle { + fn from(point: PodRistrettoPoint) -> Self { + DecryptHandle(point.0) + } +} diff --git a/zk-token-sdk/src/pod/mod.rs b/zk-token-sdk/src/pod/mod.rs index a011f3ff9ecfa8..c27cd648a91c6c 100644 --- a/zk-token-sdk/src/pod/mod.rs +++ b/zk-token-sdk/src/pod/mod.rs @@ -1,6 +1,7 @@ pub mod auth_encryption; pub mod elgamal; pub mod instruction; +pub mod ops; pub mod pedersen; pub mod range_proof; pub mod sigma_proofs; diff --git a/zk-token-sdk/src/pod/ops.rs b/zk-token-sdk/src/pod/ops.rs index c96ad970d53a25..4a64c2462ae43a 100644 --- a/zk-token-sdk/src/pod/ops.rs +++ b/zk-token-sdk/src/pod/ops.rs @@ -3,7 +3,7 @@ use crate::{ ristretto::{add_ristretto, multiply_ristretto, subtract_ristretto, PodRistrettoPoint}, scalar::PodScalar, }, - zk_token_elgamal::{elgamal::*, pedersen::*}, + pod::{elgamal::*, pedersen::*}, }; const SHIFT_BITS: usize = 16; @@ -129,7 +129,7 @@ mod tests { pedersen::{Pedersen, PedersenOpening}, }, instruction::split_u64, - zk_token_elgamal::{ops, pod}, + pod::{self, ops}, }, bytemuck::Zeroable, curve25519_dalek::scalar::Scalar, diff --git a/zk-token-sdk/src/pod/pedersen.rs b/zk-token-sdk/src/pod/pedersen.rs index 8448853b2a775e..161609a06f0010 100644 --- a/zk-token-sdk/src/pod/pedersen.rs +++ b/zk-token-sdk/src/pod/pedersen.rs @@ -1,5 +1,6 @@ use { crate::{ + curve25519::ristretto::PodRistrettoPoint, encryption::pedersen, errors::ProofError, pod::{Pod, Zeroable}, @@ -41,3 +42,15 @@ impl TryFrom for pedersen::PedersenCommitment { Self::from_bytes(&pod.0).ok_or(ProofError::CiphertextDeserialization) } } + +impl From for PodRistrettoPoint { + fn from(commitment: PedersenCommitment) -> Self { + PodRistrettoPoint(commitment.0) + } +} + +impl From for PedersenCommitment { + fn from(point: PodRistrettoPoint) -> Self { + PedersenCommitment(point.0) + } +} From 5f63834c3c3d12873f267c9eff580c4b78b244d7 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 18:17:54 +0900 Subject: [PATCH 08/11] refactor `pod` as a submodule of `zk_token_elgamal` --- zk-token-sdk/src/lib.rs | 2 +- zk-token-sdk/src/pod/mod.rs | 74 ------------------- zk-token-sdk/src/transcript.rs | 2 +- .../src/{pod => zk_token_elgamal}/convert.rs | 0 .../{pod => zk_token_elgamal}/decryption.rs | 0 zk-token-sdk/src/zk_token_elgamal/mod.rs | 2 + .../src/{pod => zk_token_elgamal}/ops.rs | 0 .../src/{pod => zk_token_elgamal}/pod.rs | 0 .../pod/auth_encryption.rs | 0 .../src/{ => zk_token_elgamal}/pod/elgamal.rs | 0 .../{ => zk_token_elgamal}/pod/instruction.rs | 0 .../{ => zk_token_elgamal}/pod/pedersen.rs | 0 .../{ => zk_token_elgamal}/pod/range_proof.rs | 0 .../pod/sigma_proofs.rs | 0 14 files changed, 4 insertions(+), 76 deletions(-) delete mode 100644 zk-token-sdk/src/pod/mod.rs rename zk-token-sdk/src/{pod => zk_token_elgamal}/convert.rs (100%) rename zk-token-sdk/src/{pod => zk_token_elgamal}/decryption.rs (100%) create mode 100644 zk-token-sdk/src/zk_token_elgamal/mod.rs rename zk-token-sdk/src/{pod => zk_token_elgamal}/ops.rs (100%) rename zk-token-sdk/src/{pod => zk_token_elgamal}/pod.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/auth_encryption.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/elgamal.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/instruction.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/pedersen.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/range_proof.rs (100%) rename zk-token-sdk/src/{ => zk_token_elgamal}/pod/sigma_proofs.rs (100%) diff --git a/zk-token-sdk/src/lib.rs b/zk-token-sdk/src/lib.rs index 23c4612c6ec758..14ce5b4380af47 100644 --- a/zk-token-sdk/src/lib.rs +++ b/zk-token-sdk/src/lib.rs @@ -34,7 +34,7 @@ mod transcript; // TODO: re-organize visibility pub mod curve25519; pub mod instruction; -pub mod pod; +pub mod zk_token_elgamal; pub mod zk_token_proof_instruction; pub mod zk_token_proof_program; pub mod zk_token_proof_state; diff --git a/zk-token-sdk/src/pod/mod.rs b/zk-token-sdk/src/pod/mod.rs deleted file mode 100644 index c27cd648a91c6c..00000000000000 --- a/zk-token-sdk/src/pod/mod.rs +++ /dev/null @@ -1,74 +0,0 @@ -pub mod auth_encryption; -pub mod elgamal; -pub mod instruction; -pub mod ops; -pub mod pedersen; -pub mod range_proof; -pub mod sigma_proofs; - -use { - crate::zk_token_proof_instruction::ProofType, - num_traits::{FromPrimitive, ToPrimitive}, - solana_program::instruction::InstructionError, -}; - -pub use { - auth_encryption::AeCiphertext, - bytemuck::{Pod, Zeroable}, - elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, - instruction::{ - FeeEncryption, FeeParameters, TransferAmountEncryption, TransferPubkeys, - TransferWithFeePubkeys, - }, - pedersen::PedersenCommitment, - range_proof::{RangeProof128, RangeProof256, RangeProof64}, - sigma_proofs::{ - AggregatedValidityProof, CiphertextCiphertextEqualityProof, - CiphertextCommitmentEqualityProof, FeeSigmaProof, PubkeyValidityProof, ValidityProof, - ZeroBalanceProof, - }, -}; - -#[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) - } -} diff --git a/zk-token-sdk/src/transcript.rs b/zk-token-sdk/src/transcript.rs index a4e14e300dbc7e..c0ed1161666c9e 100644 --- a/zk-token-sdk/src/transcript.rs +++ b/zk-token-sdk/src/transcript.rs @@ -1,5 +1,5 @@ use { - crate::{errors::TranscriptError, pod}, + crate::{errors::TranscriptError, zk_token_elgamal::pod}, curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar, traits::IsIdentity}, merlin::Transcript, }; diff --git a/zk-token-sdk/src/pod/convert.rs b/zk-token-sdk/src/zk_token_elgamal/convert.rs similarity index 100% rename from zk-token-sdk/src/pod/convert.rs rename to zk-token-sdk/src/zk_token_elgamal/convert.rs diff --git a/zk-token-sdk/src/pod/decryption.rs b/zk-token-sdk/src/zk_token_elgamal/decryption.rs similarity index 100% rename from zk-token-sdk/src/pod/decryption.rs rename to zk-token-sdk/src/zk_token_elgamal/decryption.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/mod.rs b/zk-token-sdk/src/zk_token_elgamal/mod.rs new file mode 100644 index 00000000000000..3a2397550850f7 --- /dev/null +++ b/zk-token-sdk/src/zk_token_elgamal/mod.rs @@ -0,0 +1,2 @@ +pub mod ops; +pub mod pod; diff --git a/zk-token-sdk/src/pod/ops.rs b/zk-token-sdk/src/zk_token_elgamal/ops.rs similarity index 100% rename from zk-token-sdk/src/pod/ops.rs rename to zk-token-sdk/src/zk_token_elgamal/ops.rs diff --git a/zk-token-sdk/src/pod/pod.rs b/zk-token-sdk/src/zk_token_elgamal/pod.rs similarity index 100% rename from zk-token-sdk/src/pod/pod.rs rename to zk-token-sdk/src/zk_token_elgamal/pod.rs diff --git a/zk-token-sdk/src/pod/auth_encryption.rs b/zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs similarity index 100% rename from zk-token-sdk/src/pod/auth_encryption.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs diff --git a/zk-token-sdk/src/pod/elgamal.rs b/zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs similarity index 100% rename from zk-token-sdk/src/pod/elgamal.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs diff --git a/zk-token-sdk/src/pod/instruction.rs b/zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs similarity index 100% rename from zk-token-sdk/src/pod/instruction.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs diff --git a/zk-token-sdk/src/pod/pedersen.rs b/zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs similarity index 100% rename from zk-token-sdk/src/pod/pedersen.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs diff --git a/zk-token-sdk/src/pod/range_proof.rs b/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs similarity index 100% rename from zk-token-sdk/src/pod/range_proof.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs diff --git a/zk-token-sdk/src/pod/sigma_proofs.rs b/zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs similarity index 100% rename from zk-token-sdk/src/pod/sigma_proofs.rs rename to zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs From ea2fabe15aade91b1f82233da6940ccf3e0faf34 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 18:23:29 +0900 Subject: [PATCH 09/11] clean up `convert`, `decryption`, and `pod` modules --- .../src/instruction/ctxt_ctxt_equality.rs | 2 +- .../src/instruction/pubkey_validity.rs | 2 +- zk-token-sdk/src/instruction/transfer.rs | 2 +- .../src/instruction/transfer_with_fee.rs | 2 +- zk-token-sdk/src/instruction/withdraw.rs | 2 +- zk-token-sdk/src/instruction/zero_balance.rs | 2 +- zk-token-sdk/src/zk_token_elgamal/convert.rs | 119 ------------------ .../src/zk_token_elgamal/decryption.rs | 35 ------ zk-token-sdk/src/zk_token_elgamal/ops.rs | 4 +- zk-token-sdk/src/zk_token_elgamal/pod.rs | 6 - .../zk_token_elgamal/pod/auth_encryption.rs | 2 +- .../src/zk_token_elgamal/pod/elgamal.rs | 2 +- .../src/zk_token_elgamal/pod/instruction.rs | 2 +- .../src/zk_token_elgamal/pod/pedersen.rs | 2 +- .../src/zk_token_elgamal/pod/range_proof.rs | 72 ++++++++++- .../src/zk_token_elgamal/pod/sigma_proofs.rs | 2 +- zk-token-sdk/src/zk_token_proof_state.rs | 2 +- 17 files changed, 85 insertions(+), 175 deletions(-) delete mode 100644 zk-token-sdk/src/zk_token_elgamal/convert.rs delete mode 100644 zk-token-sdk/src/zk_token_elgamal/decryption.rs delete mode 100644 zk-token-sdk/src/zk_token_elgamal/pod.rs diff --git a/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs b/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs index c9bc50b19bbffb..de2e8e07de046f 100644 --- a/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs +++ b/zk-token-sdk/src/instruction/ctxt_ctxt_equality.rs @@ -25,7 +25,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/pubkey_validity.rs b/zk-token-sdk/src/instruction/pubkey_validity.rs index e877d01ad33889..699b18885b3e63 100644 --- a/zk-token-sdk/src/instruction/pubkey_validity.rs +++ b/zk-token-sdk/src/instruction/pubkey_validity.rs @@ -17,7 +17,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/transfer.rs b/zk-token-sdk/src/instruction/transfer.rs index b9bb6bc6b22f74..a153b6b3076f24 100644 --- a/zk-token-sdk/src/instruction/transfer.rs +++ b/zk-token-sdk/src/instruction/transfer.rs @@ -24,7 +24,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/transfer_with_fee.rs b/zk-token-sdk/src/instruction/transfer_with_fee.rs index 614bc7d2e54b50..213d9356f24388 100644 --- a/zk-token-sdk/src/instruction/transfer_with_fee.rs +++ b/zk-token-sdk/src/instruction/transfer_with_fee.rs @@ -29,7 +29,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/withdraw.rs b/zk-token-sdk/src/instruction/withdraw.rs index 9bb674562d60df..2ddd1462b0dbf6 100644 --- a/zk-token-sdk/src/instruction/withdraw.rs +++ b/zk-token-sdk/src/instruction/withdraw.rs @@ -16,7 +16,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/instruction/zero_balance.rs b/zk-token-sdk/src/instruction/zero_balance.rs index 5c34676a56f97f..672ada7d9b6890 100644 --- a/zk-token-sdk/src/instruction/zero_balance.rs +++ b/zk-token-sdk/src/instruction/zero_balance.rs @@ -18,7 +18,7 @@ use { use { crate::{ instruction::{ProofType, ZkProofData}, - pod, + zk_token_elgamal::pod, }, bytemuck::{Pod, Zeroable}, }; diff --git a/zk-token-sdk/src/zk_token_elgamal/convert.rs b/zk-token-sdk/src/zk_token_elgamal/convert.rs deleted file mode 100644 index e85e56e99c0949..00000000000000 --- a/zk-token-sdk/src/zk_token_elgamal/convert.rs +++ /dev/null @@ -1,119 +0,0 @@ -pub use target_arch::*; -use {super::pod, crate::curve25519::ristretto::PodRistrettoPoint}; - -#[cfg(not(target_os = "solana"))] -mod target_arch { - use { - super::pod, - crate::{ - curve25519::scalar::PodScalar, - errors::ProofError, - instruction::{ - transfer::{TransferAmountEncryption, TransferPubkeys}, - transfer_with_fee::{FeeEncryption, FeeParameters, TransferWithFeePubkeys}, - }, - }, - curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar}, - std::convert::TryFrom, - }; - - impl From for PodScalar { - fn from(scalar: Scalar) -> Self { - Self(scalar.to_bytes()) - } - } - - impl TryFrom for Scalar { - type Error = ProofError; - - fn try_from(pod: PodScalar) -> Result { - Scalar::from_canonical_bytes(pod.0).ok_or(ProofError::CiphertextDeserialization) - } - } - - impl From for pod::CompressedRistretto { - fn from(cr: CompressedRistretto) -> Self { - Self(cr.to_bytes()) - } - } - - impl From for CompressedRistretto { - fn from(pod: pod::CompressedRistretto) -> Self { - Self(pod.0) - } - } -} - -#[cfg(target_os = "solana")] -#[allow(unused_variables)] -mod target_arch {} - -#[cfg(test)] -mod tests { - use { - super::*, - crate::{encryption::pedersen::Pedersen, range_proof::RangeProof}, - merlin::Transcript, - std::convert::TryInto, - }; - - #[test] - fn test_pod_range_proof_64() { - let (comm, open) = Pedersen::new(55_u64); - - let mut transcript_create = Transcript::new(b"Test"); - let mut transcript_verify = Transcript::new(b"Test"); - - let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); - - let proof_serialized: pod::RangeProof64 = proof.try_into().unwrap(); - let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); - - assert!(proof_deserialized - .verify(vec![&comm], vec![64], &mut transcript_verify) - .is_ok()); - - // should fail to serialize to pod::RangeProof128 - let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); - - assert!(TryInto::::try_into(proof).is_err()); - } - - #[test] - fn test_pod_range_proof_128() { - let (comm_1, open_1) = Pedersen::new(55_u64); - let (comm_2, open_2) = Pedersen::new(77_u64); - let (comm_3, open_3) = Pedersen::new(99_u64); - - let mut transcript_create = Transcript::new(b"Test"); - let mut transcript_verify = Transcript::new(b"Test"); - - let proof = RangeProof::new( - vec![55, 77, 99], - vec![64, 32, 32], - vec![&open_1, &open_2, &open_3], - &mut transcript_create, - ); - - let proof_serialized: pod::RangeProof128 = proof.try_into().unwrap(); - let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); - - assert!(proof_deserialized - .verify( - vec![&comm_1, &comm_2, &comm_3], - vec![64, 32, 32], - &mut transcript_verify, - ) - .is_ok()); - - // should fail to serialize to pod::RangeProof64 - let proof = RangeProof::new( - vec![55, 77, 99], - vec![64, 32, 32], - vec![&open_1, &open_2, &open_3], - &mut transcript_create, - ); - - assert!(TryInto::::try_into(proof).is_err()); - } -} diff --git a/zk-token-sdk/src/zk_token_elgamal/decryption.rs b/zk-token-sdk/src/zk_token_elgamal/decryption.rs deleted file mode 100644 index a207b909d05242..00000000000000 --- a/zk-token-sdk/src/zk_token_elgamal/decryption.rs +++ /dev/null @@ -1,35 +0,0 @@ -#[cfg(not(target_os = "solana"))] -use crate::{ - encryption::elgamal::{ElGamalCiphertext, ElGamalSecretKey}, - zk_token_elgamal::pod, -}; - -#[cfg(not(target_os = "solana"))] -impl pod::ElGamalCiphertext { - pub fn decrypt(self, secret_key: &ElGamalSecretKey) -> Option { - let deserialized_ciphertext: Option = self.try_into().ok(); - if let Some(ciphertext) = deserialized_ciphertext { - ciphertext.decrypt_u32(secret_key) - } else { - None - } - } -} - -#[cfg(test)] -mod tests { - use {super::*, crate::encryption::elgamal::ElGamalKeypair}; - - #[test] - fn test_pod_decryption() { - let keypair = ElGamalKeypair::new_rand(); - - let pod_ciphertext = pod::ElGamalCiphertext([0u8; 64]); - assert_eq!(pod_ciphertext.decrypt(&keypair.secret).unwrap(), 0); - - let amount = 55_u64; - let ciphertext = keypair.public.encrypt(amount); - let pod_ciphertext: pod::ElGamalCiphertext = ciphertext.into(); - assert_eq!(pod_ciphertext.decrypt(&keypair.secret).unwrap(), 55); - } -} diff --git a/zk-token-sdk/src/zk_token_elgamal/ops.rs b/zk-token-sdk/src/zk_token_elgamal/ops.rs index 4a64c2462ae43a..5bc8f357139831 100644 --- a/zk-token-sdk/src/zk_token_elgamal/ops.rs +++ b/zk-token-sdk/src/zk_token_elgamal/ops.rs @@ -3,7 +3,7 @@ use crate::{ ristretto::{add_ristretto, multiply_ristretto, subtract_ristretto, PodRistrettoPoint}, scalar::PodScalar, }, - pod::{elgamal::*, pedersen::*}, + zk_token_elgamal::pod::{elgamal::*, pedersen::*}, }; const SHIFT_BITS: usize = 16; @@ -129,7 +129,7 @@ mod tests { pedersen::{Pedersen, PedersenOpening}, }, instruction::split_u64, - pod::{self, ops}, + zk_token_elgamal::pod::{self, ops}, }, bytemuck::Zeroable, curve25519_dalek::scalar::Scalar, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod.rs b/zk-token-sdk/src/zk_token_elgamal/pod.rs deleted file mode 100644 index ba84b492fee86d..00000000000000 --- a/zk-token-sdk/src/zk_token_elgamal/pod.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::pod::{elgamal::*, pedersen::*, PodU16, PodU64}; -pub use bytemuck::{Pod, Zeroable}; - -#[derive(Clone, Copy, Pod, Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct CompressedRistretto(pub [u8; 32]); diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs b/zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs index ef6086f3f0b964..c5aba38826bec9 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/auth_encryption.rs @@ -2,7 +2,7 @@ use { crate::{ encryption::auth_encryption, errors::ProofError, - pod::{Pod, Zeroable}, + zk_token_elgamal::pod::{Pod, Zeroable}, }, base64::{prelude::BASE64_STANDARD, Engine}, std::fmt, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs b/zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs index 8d6ab8f96b6255..2518c75c00955e 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/elgamal.rs @@ -3,7 +3,7 @@ use { curve25519::ristretto::PodRistrettoPoint, encryption::elgamal, errors::ProofError, - pod::{pedersen::PedersenCommitment, Pod, Zeroable}, + zk_token_elgamal::pod::{pedersen::PedersenCommitment, Pod, Zeroable}, }, base64::{prelude::BASE64_STANDARD, Engine}, curve25519_dalek::ristretto::CompressedRistretto, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs b/zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs index 013357c5e8d060..0d61b60cf08560 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs @@ -1,7 +1,7 @@ use crate::{ errors::ProofError, instruction::{transfer, transfer_with_fee}, - pod::{elgamal::*, pedersen::*, Pod, PodU16, PodU64, Zeroable}, + zk_token_elgamal::pod::{elgamal::*, pedersen::*, Pod, PodU16, PodU64, Zeroable}, }; #[derive(Clone, Copy, Pod, Zeroable)] diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs b/zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs index 161609a06f0010..3d17a0eb1fe30f 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/pedersen.rs @@ -3,7 +3,7 @@ use { curve25519::ristretto::PodRistrettoPoint, encryption::pedersen, errors::ProofError, - pod::{Pod, Zeroable}, + zk_token_elgamal::pod::{Pod, Zeroable}, }, curve25519_dalek::ristretto::CompressedRistretto, std::fmt, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs b/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs index 944f5a794645ab..d88274b0c6e1bd 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs @@ -1,7 +1,7 @@ use crate::{ errors::ProofVerificationError, - pod::{Pod, Zeroable}, range_proof::{self, errors::RangeProofError}, + zk_token_elgamal::pod::{Pod, Zeroable}, }; /// Serialization of range proofs for 64-bit numbers (for `Withdraw` instruction) @@ -126,3 +126,73 @@ impl TryFrom for range_proof::RangeProof { Self::from_bytes(&pod.0) } } + +#[cfg(test)] +mod tests { + use { + super::*, + crate::{encryption::pedersen::Pedersen, range_proof::RangeProof}, + merlin::Transcript, + std::convert::TryInto, + }; + + #[test] + fn test_pod_range_proof_64() { + let (comm, open) = Pedersen::new(55_u64); + + let mut transcript_create = Transcript::new(b"Test"); + let mut transcript_verify = Transcript::new(b"Test"); + + let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); + + let proof_serialized: pod::RangeProof64 = proof.try_into().unwrap(); + let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); + + assert!(proof_deserialized + .verify(vec![&comm], vec![64], &mut transcript_verify) + .is_ok()); + + // should fail to serialize to pod::RangeProof128 + let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); + + assert!(TryInto::::try_into(proof).is_err()); + } + + #[test] + fn test_pod_range_proof_128() { + let (comm_1, open_1) = Pedersen::new(55_u64); + let (comm_2, open_2) = Pedersen::new(77_u64); + let (comm_3, open_3) = Pedersen::new(99_u64); + + let mut transcript_create = Transcript::new(b"Test"); + let mut transcript_verify = Transcript::new(b"Test"); + + let proof = RangeProof::new( + vec![55, 77, 99], + vec![64, 32, 32], + vec![&open_1, &open_2, &open_3], + &mut transcript_create, + ); + + let proof_serialized: pod::RangeProof128 = proof.try_into().unwrap(); + let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); + + assert!(proof_deserialized + .verify( + vec![&comm_1, &comm_2, &comm_3], + vec![64, 32, 32], + &mut transcript_verify, + ) + .is_ok()); + + // should fail to serialize to pod::RangeProof64 + let proof = RangeProof::new( + vec![55, 77, 99], + vec![64, 32, 32], + vec![&open_1, &open_2, &open_3], + &mut transcript_create, + ); + + assert!(TryInto::::try_into(proof).is_err()); + } +} diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs b/zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs index 2f00a435aba0c1..7c30a01542c640 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/sigma_proofs.rs @@ -1,9 +1,9 @@ use crate::{ - pod::{Pod, Zeroable}, sigma_proofs::{ ctxt_comm_equality_proof, ctxt_ctxt_equality_proof, errors::*, fee_proof, pubkey_proof, validity_proof, zero_balance_proof, }, + zk_token_elgamal::pod::{Pod, Zeroable}, }; /// Serialization of `CiphertextCommitmentEqualityProof` diff --git a/zk-token-sdk/src/zk_token_proof_state.rs b/zk-token-sdk/src/zk_token_proof_state.rs index 9651dd299872a7..d95aa4f11ec1c3 100644 --- a/zk-token-sdk/src/zk_token_proof_state.rs +++ b/zk-token-sdk/src/zk_token_proof_state.rs @@ -1,5 +1,5 @@ use { - crate::{pod::PodProofType, zk_token_proof_instruction::ProofType}, + crate::{zk_token_elgamal::pod::PodProofType, zk_token_proof_instruction::ProofType}, bytemuck::{bytes_of, Pod, Zeroable}, num_traits::ToPrimitive, solana_program::{ From b6354d9768a8aaae897816f5ef732819d6b1fdc4 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 18:25:48 +0900 Subject: [PATCH 10/11] refactor range proof tests --- zk-token-sdk/src/zk_token_elgamal/ops.rs | 2 +- zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/zk-token-sdk/src/zk_token_elgamal/ops.rs b/zk-token-sdk/src/zk_token_elgamal/ops.rs index 5bc8f357139831..7fb9b138490333 100644 --- a/zk-token-sdk/src/zk_token_elgamal/ops.rs +++ b/zk-token-sdk/src/zk_token_elgamal/ops.rs @@ -129,7 +129,7 @@ mod tests { pedersen::{Pedersen, PedersenOpening}, }, instruction::split_u64, - zk_token_elgamal::pod::{self, ops}, + zk_token_elgamal::{ops, pod}, }, bytemuck::Zeroable, curve25519_dalek::scalar::Scalar, diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs b/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs index d88274b0c6e1bd..294b3aebc64741 100644 --- a/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs +++ b/zk-token-sdk/src/zk_token_elgamal/pod/range_proof.rs @@ -145,17 +145,17 @@ mod tests { let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); - let proof_serialized: pod::RangeProof64 = proof.try_into().unwrap(); + let proof_serialized: RangeProof64 = proof.try_into().unwrap(); let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); assert!(proof_deserialized .verify(vec![&comm], vec![64], &mut transcript_verify) .is_ok()); - // should fail to serialize to pod::RangeProof128 + // should fail to serialize to RangeProof128 let proof = RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create); - assert!(TryInto::::try_into(proof).is_err()); + assert!(TryInto::::try_into(proof).is_err()); } #[test] @@ -174,7 +174,7 @@ mod tests { &mut transcript_create, ); - let proof_serialized: pod::RangeProof128 = proof.try_into().unwrap(); + let proof_serialized: RangeProof128 = proof.try_into().unwrap(); let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap(); assert!(proof_deserialized @@ -185,7 +185,7 @@ mod tests { ) .is_ok()); - // should fail to serialize to pod::RangeProof64 + // should fail to serialize to RangeProof64 let proof = RangeProof::new( vec![55, 77, 99], vec![64, 32, 32], @@ -193,6 +193,6 @@ mod tests { &mut transcript_create, ); - assert!(TryInto::::try_into(proof).is_err()); + assert!(TryInto::::try_into(proof).is_err()); } } From b540e502af36563d4a8084d04343ed969c304a38 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 23 May 2023 18:37:03 +0900 Subject: [PATCH 11/11] add `pod/mod.rs` --- zk-token-sdk/src/zk_token_elgamal/pod/mod.rs | 72 ++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 zk-token-sdk/src/zk_token_elgamal/pod/mod.rs diff --git a/zk-token-sdk/src/zk_token_elgamal/pod/mod.rs b/zk-token-sdk/src/zk_token_elgamal/pod/mod.rs new file mode 100644 index 00000000000000..39eea0763ff263 --- /dev/null +++ b/zk-token-sdk/src/zk_token_elgamal/pod/mod.rs @@ -0,0 +1,72 @@ +pub mod auth_encryption; +pub mod elgamal; +pub mod instruction; +pub mod pedersen; +pub mod range_proof; +pub mod sigma_proofs; + +use { + crate::zk_token_proof_instruction::ProofType, + num_traits::{FromPrimitive, ToPrimitive}, + solana_program::instruction::InstructionError, +}; +pub use { + auth_encryption::AeCiphertext, + bytemuck::{Pod, Zeroable}, + elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, + instruction::{ + FeeEncryption, FeeParameters, TransferAmountEncryption, TransferPubkeys, + TransferWithFeePubkeys, + }, + pedersen::PedersenCommitment, + range_proof::{RangeProof128, RangeProof256, RangeProof64}, + sigma_proofs::{ + AggregatedValidityProof, CiphertextCiphertextEqualityProof, + CiphertextCommitmentEqualityProof, FeeSigmaProof, PubkeyValidityProof, ValidityProof, + ZeroBalanceProof, + }, +}; + +#[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) + } +}