From 3e50b16b4c2b6388233d4105658d9134f0cc1ab8 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Fri, 17 Oct 2025 13:49:47 +0900 Subject: [PATCH 1/7] create `solana-zk-sdk-pod` and migrate encryption pod types --- Cargo.lock | 11 ++ Cargo.toml | 3 +- zk-sdk-pod/Cargo.toml | 25 +++ zk-sdk-pod/src/encryption/auth_encryption.rs | 51 ++++++ zk-sdk-pod/src/encryption/elgamal.rs | 104 ++++++++++++ zk-sdk-pod/src/encryption/grouped_elgamal.rs | 138 ++++++++++++++++ zk-sdk-pod/src/encryption/mod.rs | 34 ++++ zk-sdk-pod/src/encryption/pedersen.rs | 42 +++++ zk-sdk-pod/src/errors.rs | 11 ++ zk-sdk-pod/src/lib.rs | 10 ++ zk-sdk-pod/src/macros.rs | 34 ++++ zk-sdk/Cargo.toml | 1 + zk-sdk/src/encryption/pod/auth_encryption.rs | 50 +----- zk-sdk/src/encryption/pod/elgamal.rs | 125 ++------------- zk-sdk/src/encryption/pod/grouped_elgamal.rs | 150 ++---------------- zk-sdk/src/encryption/pod/pedersen.rs | 57 ++----- zk-sdk/src/range_proof/mod.rs | 7 +- .../handles_2.rs | 13 +- .../handles_3.rs | 13 +- .../ciphertext_ciphertext_equality.rs | 6 +- .../ciphertext_commitment_equality.rs | 13 +- .../grouped_ciphertext_validity/handles_2.rs | 13 +- .../grouped_ciphertext_validity/handles_3.rs | 13 +- .../src/sigma_proofs/percentage_with_cap.rs | 6 +- zk-sdk/src/sigma_proofs/pubkey_validity.rs | 12 +- zk-sdk/src/sigma_proofs/zero_ciphertext.rs | 2 +- .../handles_2.rs | 20 +-- .../handles_3.rs | 20 +-- .../proof_data/batched_range_proof/mod.rs | 2 +- .../ciphertext_ciphertext_equality.rs | 16 +- .../ciphertext_commitment_equality.rs | 22 +-- .../grouped_ciphertext_validity/handles_2.rs | 20 +-- .../grouped_ciphertext_validity/handles_3.rs | 20 +-- .../proof_data/percentage_with_cap.rs | 2 +- .../proof_data/pubkey_validity.rs | 2 +- .../proof_data/zero_ciphertext.rs | 2 +- 36 files changed, 596 insertions(+), 474 deletions(-) create mode 100644 zk-sdk-pod/Cargo.toml create mode 100644 zk-sdk-pod/src/encryption/auth_encryption.rs create mode 100644 zk-sdk-pod/src/encryption/elgamal.rs create mode 100644 zk-sdk-pod/src/encryption/grouped_elgamal.rs create mode 100644 zk-sdk-pod/src/encryption/mod.rs create mode 100644 zk-sdk-pod/src/encryption/pedersen.rs create mode 100644 zk-sdk-pod/src/errors.rs create mode 100644 zk-sdk-pod/src/lib.rs create mode 100644 zk-sdk-pod/src/macros.rs diff --git a/Cargo.lock b/Cargo.lock index 2ab4bee..ada04f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -951,12 +951,23 @@ dependencies = [ "solana-seed-phrase", "solana-signature", "solana-signer", + "solana-zk-sdk-pod", "subtle", "thiserror 2.0.17", "tiny-bip39", "zeroize", ] +[[package]] +name = "solana-zk-sdk-pod" +version = "0.1.0" +dependencies = [ + "base64", + "bytemuck", + "bytemuck_derive", + "thiserror 2.0.17", +] + [[package]] name = "solana-zk-sdk-wasm-js" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index a353033..8cc9ded 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["zk-sdk", "zk-sdk-wasm-js"] +members = ["zk-sdk", "zk-sdk-pod", "zk-sdk-wasm-js"] [workspace.package] authors = ["Anza Maintainers "] @@ -53,6 +53,7 @@ solana-seed-phrase = "3.0.0" solana-signature = { version = "3.0.0", default-features = false } solana-signer = "3.0.0" solana-zk-sdk = { path = "zk-sdk", version = "4.0.0" } +solana-zk-sdk-pod = { path = "zk-sdk-pod", version = "0.1.0" } solana-zk-sdk-wasm-js = { path = "zk-sdk-wasm-js", version = "0.1.0" } subtle = "2.6.1" thiserror = "2.0.17" diff --git a/zk-sdk-pod/Cargo.toml b/zk-sdk-pod/Cargo.toml new file mode 100644 index 0000000..3dc8398 --- /dev/null +++ b/zk-sdk-pod/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "solana-zk-sdk-pod" +description = "Solana ZK SDK Plain Old Data (Pod)" +documentation = "https://docs.rs/solana-zk-sdk-pod" +version = "0.1.0" +authors = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +edition = { workspace = true } + +[dependencies] +base64 = { workspace = true } +bytemuck = { workspace = true } +bytemuck_derive = { workspace = true } +thiserror = { workspace = true } + +[lib] +crate-type = ["rlib"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lints] +workspace = true diff --git a/zk-sdk-pod/src/encryption/auth_encryption.rs b/zk-sdk-pod/src/encryption/auth_encryption.rs new file mode 100644 index 0000000..a359930 --- /dev/null +++ b/zk-sdk-pod/src/encryption/auth_encryption.rs @@ -0,0 +1,51 @@ +//! Plain Old Data types for the AES128-GCM-SIV authenticated encryption scheme. + +use { + crate::{ + encryption::AE_CIPHERTEXT_LEN, + macros::{impl_from_bytes, impl_from_str}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + bytemuck::{Pod, Zeroable}, + std::fmt, +}; + +/// Maximum length of a base64 encoded authenticated encryption ciphertext +const AE_CIPHERTEXT_MAX_BASE64_LEN: usize = 48; + +/// The `AeCiphertext` type as a `Pod`. +#[derive(Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodAeCiphertext(pub [u8; AE_CIPHERTEXT_LEN]); + +// `PodAeCiphertext` is a wrapper type for a byte array, which is both `Pod` and `Zeroable`. However, +// the marker traits `bytemuck::Pod` and `bytemuck::Zeroable` can only be derived for power-of-two +// length byte arrays. Directly implement these traits for `PodAeCiphertext`. +unsafe impl Zeroable for PodAeCiphertext {} +unsafe impl Pod for PodAeCiphertext {} + +impl fmt::Debug for PodAeCiphertext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Display for PodAeCiphertext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodAeCiphertext, + BYTES_LEN = AE_CIPHERTEXT_LEN, + BASE64_LEN = AE_CIPHERTEXT_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodAeCiphertext, BYTES_LEN = AE_CIPHERTEXT_LEN); + +impl Default for PodAeCiphertext { + fn default() -> Self { + Self::zeroed() + } +} diff --git a/zk-sdk-pod/src/encryption/elgamal.rs b/zk-sdk-pod/src/encryption/elgamal.rs new file mode 100644 index 0000000..3559c43 --- /dev/null +++ b/zk-sdk-pod/src/encryption/elgamal.rs @@ -0,0 +1,104 @@ +//! Plain Old Data types for the ElGamal encryption scheme. + +use { + crate::{ + encryption::{DECRYPT_HANDLE_LEN, ELGAMAL_CIPHERTEXT_LEN, ELGAMAL_PUBKEY_LEN}, + macros::{impl_from_bytes, impl_from_str}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + bytemuck::Zeroable, + std::fmt, +}; + +/// Maximum length of a base64 encoded ElGamal public key +const ELGAMAL_PUBKEY_MAX_BASE64_LEN: usize = 44; + +/// Maximum length of a base64 encoded ElGamal ciphertext +const ELGAMAL_CIPHERTEXT_MAX_BASE64_LEN: usize = 88; + +/// Maximum length of a base64 encoded ElGamal decrypt handle +const DECRYPT_HANDLE_MAX_BASE64_LEN: usize = 44; + +/// The `ElGamalCiphertext` type as a `Pod`. +#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodElGamalCiphertext(pub [u8; ELGAMAL_CIPHERTEXT_LEN]); + +impl fmt::Debug for PodElGamalCiphertext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Display for PodElGamalCiphertext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl Default for PodElGamalCiphertext { + fn default() -> Self { + Self::zeroed() + } +} + +impl_from_str!( + TYPE = PodElGamalCiphertext, + BYTES_LEN = ELGAMAL_CIPHERTEXT_LEN, + BASE64_LEN = ELGAMAL_CIPHERTEXT_MAX_BASE64_LEN +); + +impl_from_bytes!( + TYPE = PodElGamalCiphertext, + BYTES_LEN = ELGAMAL_CIPHERTEXT_LEN +); + +/// The `ElGamalPubkey` type as a `Pod`. +#[derive(Clone, Copy, Default, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodElGamalPubkey(pub [u8; ELGAMAL_PUBKEY_LEN]); + +impl fmt::Debug for PodElGamalPubkey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Display for PodElGamalPubkey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodElGamalPubkey, + BYTES_LEN = ELGAMAL_PUBKEY_LEN, + BASE64_LEN = ELGAMAL_PUBKEY_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodElGamalPubkey, BYTES_LEN = ELGAMAL_PUBKEY_LEN); + +/// The `DecryptHandle` type as a `Pod`. +#[derive(Clone, Copy, Default, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodDecryptHandle(pub [u8; DECRYPT_HANDLE_LEN]); + +impl fmt::Debug for PodDecryptHandle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Display for PodDecryptHandle { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodDecryptHandle, + BYTES_LEN = DECRYPT_HANDLE_LEN, + BASE64_LEN = DECRYPT_HANDLE_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodDecryptHandle, BYTES_LEN = DECRYPT_HANDLE_LEN); diff --git a/zk-sdk-pod/src/encryption/grouped_elgamal.rs b/zk-sdk-pod/src/encryption/grouped_elgamal.rs new file mode 100644 index 0000000..93891fb --- /dev/null +++ b/zk-sdk-pod/src/encryption/grouped_elgamal.rs @@ -0,0 +1,138 @@ +//! Plain Old Data types for the Grouped ElGamal encryption scheme. + +use { + crate::{ + encryption::{ + elgamal::PodElGamalCiphertext, pedersen::PodPedersenCommitment, DECRYPT_HANDLE_LEN, + ELGAMAL_CIPHERTEXT_LEN, PEDERSEN_COMMITMENT_LEN, + }, + macros::{impl_from_bytes, impl_from_str}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + bytemuck::Zeroable, + std::fmt, +}; + +/// Maximum length of a base64 encoded grouped ElGamal ciphertext with 2 handles +const GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES_MAX_BASE64_LEN: usize = 132; + +/// Maximum length of a base64 encoded grouped ElGamal ciphertext with 3 handles +const GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES_MAX_BASE64_LEN: usize = 176; + +macro_rules! impl_extract { + (TYPE = $type:ident) => { + impl $type { + /// Extract the commitment component from a grouped ciphertext + pub fn extract_commitment(&self) -> PodPedersenCommitment { + // `GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES` guaranteed to be at least `PEDERSEN_COMMITMENT_LEN` + let commitment = self.0[..PEDERSEN_COMMITMENT_LEN].try_into().unwrap(); + PodPedersenCommitment(commitment) + } + + /// Extract a regular ElGamal ciphertext using the decrypt handle at a specified index. + pub fn try_extract_ciphertext( + &self, + index: usize, + ) -> Result { + let mut ciphertext_bytes = [0u8; ELGAMAL_CIPHERTEXT_LEN]; + ciphertext_bytes[..PEDERSEN_COMMITMENT_LEN] + .copy_from_slice(&self.0[..PEDERSEN_COMMITMENT_LEN]); + + let handle_start = DECRYPT_HANDLE_LEN + .checked_mul(index) + .and_then(|n| n.checked_add(PEDERSEN_COMMITMENT_LEN)) + .ok_or(crate::errors::PodParseError::GroupedCiphertextIndexOutOfBounds)?; + let handle_end = handle_start + .checked_add(DECRYPT_HANDLE_LEN) + .ok_or(crate::errors::PodParseError::GroupedCiphertextIndexOutOfBounds)?; + ciphertext_bytes[PEDERSEN_COMMITMENT_LEN..].copy_from_slice( + self.0 + .get(handle_start..handle_end) + .ok_or(crate::errors::PodParseError::GroupedCiphertextIndexOutOfBounds)?, + ); + + Ok(PodElGamalCiphertext(ciphertext_bytes)) + } + } + }; +} + +/// Byte length of a grouped ElGamal ciphertext with 2 handles +const GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES: usize = + PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN; + +/// Byte length of a grouped ElGamal ciphertext with 3 handles +const GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES: usize = + PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN; + +/// The `GroupedElGamalCiphertext` type with two decryption handles as a `Pod` +#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodGroupedElGamalCiphertext2Handles(pub [u8; GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES]); + +impl fmt::Debug for PodGroupedElGamalCiphertext2Handles { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl Default for PodGroupedElGamalCiphertext2Handles { + fn default() -> Self { + Self::zeroed() + } +} + +impl fmt::Display for PodGroupedElGamalCiphertext2Handles { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodGroupedElGamalCiphertext2Handles, + BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES, + BASE64_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES_MAX_BASE64_LEN +); + +impl_from_bytes!( + TYPE = PodGroupedElGamalCiphertext2Handles, + BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES +); + +impl_extract!(TYPE = PodGroupedElGamalCiphertext2Handles); + +/// The `GroupedElGamalCiphertext` type with three decryption handles as a `Pod` +#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodGroupedElGamalCiphertext3Handles(pub [u8; GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES]); + +impl fmt::Debug for PodGroupedElGamalCiphertext3Handles { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl Default for PodGroupedElGamalCiphertext3Handles { + fn default() -> Self { + Self::zeroed() + } +} + +impl fmt::Display for PodGroupedElGamalCiphertext3Handles { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodGroupedElGamalCiphertext3Handles, + BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES, + BASE64_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES_MAX_BASE64_LEN +); + +impl_from_bytes!( + TYPE = PodGroupedElGamalCiphertext3Handles, + BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES +); + +impl_extract!(TYPE = PodGroupedElGamalCiphertext3Handles); diff --git a/zk-sdk-pod/src/encryption/mod.rs b/zk-sdk-pod/src/encryption/mod.rs new file mode 100644 index 0000000..7cc8039 --- /dev/null +++ b/zk-sdk-pod/src/encryption/mod.rs @@ -0,0 +1,34 @@ +use crate::{RISTRETTO_POINT_LEN, SCALAR_LEN}; + +pub mod auth_encryption; +pub mod elgamal; +pub mod grouped_elgamal; +pub mod pedersen; + +/// Byte length of an authenticated encryption secret key +pub const AE_KEY_LEN: usize = 16; + +/// Byte length of a complete authenticated encryption ciphertext component that includes the +/// ciphertext and nonce components +pub const AE_CIPHERTEXT_LEN: usize = 36; + +/// Byte length of a decrypt handle +pub const DECRYPT_HANDLE_LEN: usize = RISTRETTO_POINT_LEN; + +/// Byte length of an ElGamal ciphertext +pub const ELGAMAL_CIPHERTEXT_LEN: usize = PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN; + +/// Byte length of an ElGamal public key +pub const ELGAMAL_PUBKEY_LEN: usize = RISTRETTO_POINT_LEN; + +/// Byte length of an ElGamal secret key +pub const ELGAMAL_SECRET_KEY_LEN: usize = SCALAR_LEN; + +/// Byte length of an ElGamal keypair +pub const ELGAMAL_KEYPAIR_LEN: usize = ELGAMAL_PUBKEY_LEN + ELGAMAL_SECRET_KEY_LEN; + +/// Byte length of a Pedersen opening. +pub const PEDERSEN_OPENING_LEN: usize = SCALAR_LEN; + +/// Byte length of a Pedersen commitment. +pub const PEDERSEN_COMMITMENT_LEN: usize = RISTRETTO_POINT_LEN; diff --git a/zk-sdk-pod/src/encryption/pedersen.rs b/zk-sdk-pod/src/encryption/pedersen.rs new file mode 100644 index 0000000..9bd6573 --- /dev/null +++ b/zk-sdk-pod/src/encryption/pedersen.rs @@ -0,0 +1,42 @@ +//! Plain Old Data type for the Pedersen commitment scheme. + +use { + crate::{ + encryption::PEDERSEN_COMMITMENT_LEN, + macros::{impl_from_bytes, impl_from_str}, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + bytemuck_derive::{Pod, Zeroable}, + std::fmt, +}; + +/// Maximum length of a base64 encoded ElGamal public key +const PEDERSEN_COMMITMENT_MAX_BASE64_LEN: usize = 44; + +/// The `PedersenCommitment` type as a `Pod`. +#[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] +#[repr(transparent)] +pub struct PodPedersenCommitment(pub [u8; PEDERSEN_COMMITMENT_LEN]); + +impl fmt::Debug for PodPedersenCommitment { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self.0) + } +} + +impl fmt::Display for PodPedersenCommitment { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodPedersenCommitment, + BYTES_LEN = PEDERSEN_COMMITMENT_LEN, + BASE64_LEN = PEDERSEN_COMMITMENT_MAX_BASE64_LEN +); + +impl_from_bytes!( + TYPE = PodPedersenCommitment, + BYTES_LEN = PEDERSEN_COMMITMENT_LEN +); diff --git a/zk-sdk-pod/src/errors.rs b/zk-sdk-pod/src/errors.rs new file mode 100644 index 0000000..2ed8e78 --- /dev/null +++ b/zk-sdk-pod/src/errors.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug, Clone, Eq, PartialEq)] +pub enum PodParseError { + #[error("String is the wrong size")] + WrongSize, + #[error("Invalid Base64 string")] + Invalid, + #[error("Grouped ciphertext index out of bounds")] + GroupedCiphertextIndexOutOfBounds, +} diff --git a/zk-sdk-pod/src/lib.rs b/zk-sdk-pod/src/lib.rs new file mode 100644 index 0000000..a946c04 --- /dev/null +++ b/zk-sdk-pod/src/lib.rs @@ -0,0 +1,10 @@ +pub mod encryption; +pub mod errors; +pub mod macros; + +/// Byte length of a compressed Ristretto point or scalar in Curve255519 +const UNIT_LEN: usize = 32; +/// Byte length of a compressed Ristretto point in Curve25519 +const RISTRETTO_POINT_LEN: usize = UNIT_LEN; +/// Byte length of a scalar in Curve25519 +const SCALAR_LEN: usize = UNIT_LEN; diff --git a/zk-sdk-pod/src/macros.rs b/zk-sdk-pod/src/macros.rs new file mode 100644 index 0000000..953ae97 --- /dev/null +++ b/zk-sdk-pod/src/macros.rs @@ -0,0 +1,34 @@ +macro_rules! impl_from_str { + (TYPE = $type:ident, BYTES_LEN = $bytes_len:expr, BASE64_LEN = $base64_len:expr) => { + impl std::str::FromStr for $type { + type Err = crate::errors::PodParseError; + + fn from_str(s: &str) -> Result { + if s.len() > $base64_len { + return Err(Self::Err::WrongSize); + } + let mut bytes = [0u8; $bytes_len]; + let decoded_len = BASE64_STANDARD + .decode_slice(s, &mut bytes) + .map_err(|_| Self::Err::Invalid)?; + if decoded_len != $bytes_len { + Err(Self::Err::WrongSize) + } else { + Ok($type(bytes)) + } + } + } + }; +} +pub(crate) use impl_from_str; + +macro_rules! impl_from_bytes { + (TYPE = $type:ident, BYTES_LEN = $bytes_len:expr) => { + impl std::convert::From<[u8; $bytes_len]> for $type { + fn from(bytes: [u8; $bytes_len]) -> Self { + Self(bytes) + } + } + }; +} +pub(crate) use impl_from_bytes; diff --git a/zk-sdk/Cargo.toml b/zk-sdk/Cargo.toml index 10d9a56..d98b9db 100644 --- a/zk-sdk/Cargo.toml +++ b/zk-sdk/Cargo.toml @@ -21,6 +21,7 @@ num-traits = { workspace = true } solana-instruction = { workspace = true, features = ["std"] } solana-pubkey = { workspace = true, features = ["bytemuck"] } solana-sdk-ids = { workspace = true } +solana-zk-sdk-pod = { workspace = true } thiserror = { workspace = true } [target.'cfg(not(target_os = "solana"))'.dependencies] diff --git a/zk-sdk/src/encryption/pod/auth_encryption.rs b/zk-sdk/src/encryption/pod/auth_encryption.rs index 8496e77..a97a408 100644 --- a/zk-sdk/src/encryption/pod/auth_encryption.rs +++ b/zk-sdk/src/encryption/pod/auth_encryption.rs @@ -2,55 +2,7 @@ #[cfg(not(target_os = "solana"))] use crate::{encryption::auth_encryption::AeCiphertext, errors::AuthenticatedEncryptionError}; -use { - crate::{ - encryption::AE_CIPHERTEXT_LEN, - pod::{impl_from_bytes, impl_from_str}, - }, - base64::{prelude::BASE64_STANDARD, Engine}, - bytemuck::{Pod, Zeroable}, - std::fmt, -}; - -/// Maximum length of a base64 encoded authenticated encryption ciphertext -const AE_CIPHERTEXT_MAX_BASE64_LEN: usize = 48; - -/// The `AeCiphertext` type as a `Pod`. -#[derive(Clone, Copy, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodAeCiphertext(pub(crate) [u8; AE_CIPHERTEXT_LEN]); - -// `PodAeCiphertext` is a wrapper type for a byte array, which is both `Pod` and `Zeroable`. However, -// the marker traits `bytemuck::Pod` and `bytemuck::Zeroable` can only be derived for power-of-two -// length byte arrays. Directly implement these traits for `PodAeCiphertext`. -unsafe impl Zeroable for PodAeCiphertext {} -unsafe impl Pod for PodAeCiphertext {} - -impl fmt::Debug for PodAeCiphertext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl fmt::Display for PodAeCiphertext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodAeCiphertext, - BYTES_LEN = AE_CIPHERTEXT_LEN, - BASE64_LEN = AE_CIPHERTEXT_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodAeCiphertext, BYTES_LEN = AE_CIPHERTEXT_LEN); - -impl Default for PodAeCiphertext { - fn default() -> Self { - Self::zeroed() - } -} +use solana_zk_sdk_pod::encryption::auth_encryption::PodAeCiphertext; #[cfg(not(target_os = "solana"))] impl From for PodAeCiphertext { diff --git a/zk-sdk/src/encryption/pod/elgamal.rs b/zk-sdk/src/encryption/pod/elgamal.rs index 6b30f27..5737dbc 100644 --- a/zk-sdk/src/encryption/pod/elgamal.rs +++ b/zk-sdk/src/encryption/pod/elgamal.rs @@ -1,66 +1,17 @@ //! Plain Old Data types for the ElGamal encryption scheme. +use solana_zk_sdk_pod::encryption::elgamal::{ + PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey, +}; #[cfg(not(target_os = "solana"))] use { crate::{ encryption::elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, errors::ElGamalError, }, - curve25519_dalek::ristretto::CompressedRistretto, -}; -use { - crate::{ - encryption::{DECRYPT_HANDLE_LEN, ELGAMAL_CIPHERTEXT_LEN, ELGAMAL_PUBKEY_LEN}, - pod::{impl_from_bytes, impl_from_str}, - }, - base64::{prelude::BASE64_STANDARD, Engine}, - bytemuck::Zeroable, - std::fmt, + // curve25519_dalek::ristretto::CompressedRistretto, }; -/// Maximum length of a base64 encoded ElGamal public key -const ELGAMAL_PUBKEY_MAX_BASE64_LEN: usize = 44; - -/// Maximum length of a base64 encoded ElGamal ciphertext -const ELGAMAL_CIPHERTEXT_MAX_BASE64_LEN: usize = 88; - -/// Maximum length of a base64 encoded ElGamal decrypt handle -const DECRYPT_HANDLE_MAX_BASE64_LEN: usize = 44; - -/// The `ElGamalCiphertext` type as a `Pod`. -#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodElGamalCiphertext(pub(crate) [u8; ELGAMAL_CIPHERTEXT_LEN]); - -impl fmt::Debug for PodElGamalCiphertext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl fmt::Display for PodElGamalCiphertext { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl Default for PodElGamalCiphertext { - fn default() -> Self { - Self::zeroed() - } -} - -impl_from_str!( - TYPE = PodElGamalCiphertext, - BYTES_LEN = ELGAMAL_CIPHERTEXT_LEN, - BASE64_LEN = ELGAMAL_CIPHERTEXT_MAX_BASE64_LEN -); - -impl_from_bytes!( - TYPE = PodElGamalCiphertext, - BYTES_LEN = ELGAMAL_CIPHERTEXT_LEN -); - #[cfg(not(target_os = "solana"))] impl From for PodElGamalCiphertext { fn from(decoded_ciphertext: ElGamalCiphertext) -> Self { @@ -77,31 +28,6 @@ impl TryFrom for ElGamalCiphertext { } } -/// The `ElGamalPubkey` type as a `Pod`. -#[derive(Clone, Copy, Default, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodElGamalPubkey(pub(crate) [u8; ELGAMAL_PUBKEY_LEN]); - -impl fmt::Debug for PodElGamalPubkey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl fmt::Display for PodElGamalPubkey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodElGamalPubkey, - BYTES_LEN = ELGAMAL_PUBKEY_LEN, - BASE64_LEN = ELGAMAL_PUBKEY_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodElGamalPubkey, BYTES_LEN = ELGAMAL_PUBKEY_LEN); - #[cfg(not(target_os = "solana"))] impl From for PodElGamalPubkey { fn from(decoded_pubkey: ElGamalPubkey) -> Self { @@ -118,17 +44,6 @@ impl TryFrom for ElGamalPubkey { } } -/// The `DecryptHandle` type as a `Pod`. -#[derive(Clone, Copy, Default, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodDecryptHandle(pub(crate) [u8; DECRYPT_HANDLE_LEN]); - -impl fmt::Debug for PodDecryptHandle { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - #[cfg(not(target_os = "solana"))] impl From for PodDecryptHandle { fn from(decoded_handle: DecryptHandle) -> Self { @@ -136,13 +51,13 @@ impl From for PodDecryptHandle { } } -// For proof verification, interpret pod::DecryptHandle as CompressedRistretto -#[cfg(not(target_os = "solana"))] -impl From for CompressedRistretto { - fn from(pod_handle: PodDecryptHandle) -> Self { - Self(pod_handle.0) - } -} +// // For proof verification, interpret pod::DecryptHandle as CompressedRistretto +// #[cfg(not(target_os = "solana"))] +// impl From for CompressedRistretto { +// fn from(pod_handle: PodDecryptHandle) -> Self { +// Self(pod_handle.0) +// } +// } #[cfg(not(target_os = "solana"))] impl TryFrom for DecryptHandle { @@ -153,19 +68,11 @@ impl TryFrom for DecryptHandle { } } -impl fmt::Display for PodDecryptHandle { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodDecryptHandle, - BYTES_LEN = DECRYPT_HANDLE_LEN, - BASE64_LEN = DECRYPT_HANDLE_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodDecryptHandle, BYTES_LEN = DECRYPT_HANDLE_LEN); +// impl fmt::Display for PodDecryptHandle { +// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +// write!(f, "{}", BASE64_STANDARD.encode(self.0)) +// } +// } #[cfg(test)] mod tests { diff --git a/zk-sdk/src/encryption/pod/grouped_elgamal.rs b/zk-sdk/src/encryption/pod/grouped_elgamal.rs index 3a6dc48..e2e588e 100644 --- a/zk-sdk/src/encryption/pod/grouped_elgamal.rs +++ b/zk-sdk/src/encryption/pod/grouped_elgamal.rs @@ -3,107 +3,12 @@ #[cfg(not(target_os = "solana"))] use crate::encryption::grouped_elgamal::GroupedElGamalCiphertext; use { - crate::{ - encryption::{ - pod::{elgamal::PodElGamalCiphertext, pedersen::PodPedersenCommitment}, - DECRYPT_HANDLE_LEN, ELGAMAL_CIPHERTEXT_LEN, PEDERSEN_COMMITMENT_LEN, - }, - errors::ElGamalError, - pod::{impl_from_bytes, impl_from_str}, + crate::errors::ElGamalError, + solana_zk_sdk_pod::encryption::grouped_elgamal::{ + PodGroupedElGamalCiphertext2Handles, PodGroupedElGamalCiphertext3Handles, }, - base64::{prelude::BASE64_STANDARD, Engine}, - bytemuck::Zeroable, - std::fmt, }; -/// Maximum length of a base64 encoded grouped ElGamal ciphertext with 2 handles -const GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES_MAX_BASE64_LEN: usize = 132; - -/// Maximum length of a base64 encoded grouped ElGamal ciphertext with 3 handles -const GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES_MAX_BASE64_LEN: usize = 176; - -macro_rules! impl_extract { - (TYPE = $type:ident) => { - impl $type { - /// Extract the commitment component from a grouped ciphertext - pub fn extract_commitment(&self) -> PodPedersenCommitment { - // `GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES` guaranteed to be at least `PEDERSEN_COMMITMENT_LEN` - let commitment = self.0[..PEDERSEN_COMMITMENT_LEN].try_into().unwrap(); - PodPedersenCommitment(commitment) - } - - /// Extract a regular ElGamal ciphertext using the decrypt handle at a specified index. - pub fn try_extract_ciphertext( - &self, - index: usize, - ) -> Result { - let mut ciphertext_bytes = [0u8; ELGAMAL_CIPHERTEXT_LEN]; - ciphertext_bytes[..PEDERSEN_COMMITMENT_LEN] - .copy_from_slice(&self.0[..PEDERSEN_COMMITMENT_LEN]); - - let handle_start = DECRYPT_HANDLE_LEN - .checked_mul(index) - .and_then(|n| n.checked_add(PEDERSEN_COMMITMENT_LEN)) - .ok_or(ElGamalError::CiphertextDeserialization)?; - let handle_end = handle_start - .checked_add(DECRYPT_HANDLE_LEN) - .ok_or(ElGamalError::CiphertextDeserialization)?; - ciphertext_bytes[PEDERSEN_COMMITMENT_LEN..].copy_from_slice( - self.0 - .get(handle_start..handle_end) - .ok_or(ElGamalError::CiphertextDeserialization)?, - ); - - Ok(PodElGamalCiphertext(ciphertext_bytes)) - } - } - }; -} - -/// Byte length of a grouped ElGamal ciphertext with 2 handles -const GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES: usize = - PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN; - -/// Byte length of a grouped ElGamal ciphertext with 3 handles -const GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES: usize = - PEDERSEN_COMMITMENT_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN + DECRYPT_HANDLE_LEN; - -/// The `GroupedElGamalCiphertext` type with two decryption handles as a `Pod` -#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodGroupedElGamalCiphertext2Handles( - pub(crate) [u8; GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES], -); - -impl fmt::Debug for PodGroupedElGamalCiphertext2Handles { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl Default for PodGroupedElGamalCiphertext2Handles { - fn default() -> Self { - Self::zeroed() - } -} - -impl fmt::Display for PodGroupedElGamalCiphertext2Handles { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodGroupedElGamalCiphertext2Handles, - BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES, - BASE64_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES_MAX_BASE64_LEN -); - -impl_from_bytes!( - TYPE = PodGroupedElGamalCiphertext2Handles, - BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_2_HANDLES -); - #[cfg(not(target_os = "solana"))] impl From> for PodGroupedElGamalCiphertext2Handles { fn from(decoded_ciphertext: GroupedElGamalCiphertext<2>) -> Self { @@ -120,44 +25,6 @@ impl TryFrom for GroupedElGamalCiphertext<2 } } -impl_extract!(TYPE = PodGroupedElGamalCiphertext2Handles); - -/// The `GroupedElGamalCiphertext` type with three decryption handles as a `Pod` -#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodGroupedElGamalCiphertext3Handles( - pub(crate) [u8; GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES], -); - -impl fmt::Debug for PodGroupedElGamalCiphertext3Handles { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} - -impl Default for PodGroupedElGamalCiphertext3Handles { - fn default() -> Self { - Self::zeroed() - } -} - -impl fmt::Display for PodGroupedElGamalCiphertext3Handles { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodGroupedElGamalCiphertext3Handles, - BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES, - BASE64_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES_MAX_BASE64_LEN -); - -impl_from_bytes!( - TYPE = PodGroupedElGamalCiphertext3Handles, - BYTES_LEN = GROUPED_ELGAMAL_CIPHERTEXT_3_HANDLES -); - #[cfg(not(target_os = "solana"))] impl From> for PodGroupedElGamalCiphertext3Handles { fn from(decoded_ciphertext: GroupedElGamalCiphertext<3>) -> Self { @@ -174,15 +41,16 @@ impl TryFrom for GroupedElGamalCiphertext<3 } } -impl_extract!(TYPE = PodGroupedElGamalCiphertext3Handles); - #[cfg(test)] mod tests { use { super::*, crate::encryption::{ elgamal::ElGamalKeypair, grouped_elgamal::GroupedElGamal, pedersen::Pedersen, - pod::pedersen::PodPedersenCommitment, + }, + solana_zk_sdk_pod::{ + encryption::{elgamal::PodElGamalCiphertext, pedersen::PodPedersenCommitment}, + errors::PodParseError, }, }; @@ -218,7 +86,7 @@ mod tests { let err = pod_grouped_ciphertext .try_extract_ciphertext(2) .unwrap_err(); - assert_eq!(err, ElGamalError::CiphertextDeserialization); + assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); } #[test] @@ -263,6 +131,6 @@ mod tests { let err = pod_grouped_ciphertext .try_extract_ciphertext(3) .unwrap_err(); - assert_eq!(err, ElGamalError::CiphertextDeserialization); + assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); } } diff --git a/zk-sdk/src/encryption/pod/pedersen.rs b/zk-sdk/src/encryption/pod/pedersen.rs index 96d2154..484da2c 100644 --- a/zk-sdk/src/encryption/pod/pedersen.rs +++ b/zk-sdk/src/encryption/pod/pedersen.rs @@ -1,33 +1,11 @@ //! Plain Old Data type for the Pedersen commitment scheme. +use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; #[cfg(not(target_os = "solana"))] use { crate::{encryption::pedersen::PedersenCommitment, errors::ElGamalError}, - curve25519_dalek::ristretto::CompressedRistretto, + // curve25519_dalek::ristretto::CompressedRistretto, }; -use { - crate::{ - encryption::PEDERSEN_COMMITMENT_LEN, - pod::{impl_from_bytes, impl_from_str}, - }, - base64::{prelude::BASE64_STANDARD, Engine}, - bytemuck_derive::{Pod, Zeroable}, - std::fmt, -}; - -/// Maximum length of a base64 encoded ElGamal public key -const PEDERSEN_COMMITMENT_MAX_BASE64_LEN: usize = 44; - -/// The `PedersenCommitment` type as a `Pod`. -#[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct PodPedersenCommitment(pub(crate) [u8; PEDERSEN_COMMITMENT_LEN]); - -impl fmt::Debug for PodPedersenCommitment { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self.0) - } -} #[cfg(not(target_os = "solana"))] impl From for PodPedersenCommitment { @@ -36,30 +14,13 @@ impl From for PodPedersenCommitment { } } -impl fmt::Display for PodPedersenCommitment { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodPedersenCommitment, - BYTES_LEN = PEDERSEN_COMMITMENT_LEN, - BASE64_LEN = PEDERSEN_COMMITMENT_MAX_BASE64_LEN -); - -impl_from_bytes!( - TYPE = PodPedersenCommitment, - BYTES_LEN = PEDERSEN_COMMITMENT_LEN -); - -// For proof verification, interpret pod::PedersenCommitment directly as CompressedRistretto -#[cfg(not(target_os = "solana"))] -impl From for CompressedRistretto { - fn from(pod_commitment: PodPedersenCommitment) -> Self { - Self(pod_commitment.0) - } -} +// // For proof verification, interpret pod::PedersenCommitment directly as CompressedRistretto +// #[cfg(not(target_os = "solana"))] +// impl From for CompressedRistretto { +// fn from(pod_commitment: PodPedersenCommitment) -> Self { +// Self(pod_commitment.0) +// } +// } #[cfg(not(target_os = "solana"))] impl TryFrom for PedersenCommitment { diff --git a/zk-sdk/src/range_proof/mod.rs b/zk-sdk/src/range_proof/mod.rs index c31eafb..8822adc 100644 --- a/zk-sdk/src/range_proof/mod.rs +++ b/zk-sdk/src/range_proof/mod.rs @@ -514,11 +514,8 @@ fn delta(bit_lengths: &[usize], y: &Scalar, z: &Scalar) -> Scalar { #[cfg(test)] mod tests { use { - super::*, - crate::{ - encryption::pod::pedersen::PodPedersenCommitment, range_proof::pod::PodRangeProofU128, - }, - std::str::FromStr, + super::*, crate::range_proof::pod::PodRangeProofU128, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::str::FromStr, }; #[test] diff --git a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs index 2121ddd..19664bd 100644 --- a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs @@ -147,16 +147,13 @@ mod test { use { super::*, crate::{ - encryption::{ - elgamal::ElGamalKeypair, - pedersen::Pedersen, - pod::{ - elgamal::{PodDecryptHandle, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - }, + encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, sigma_proofs::pod::PodBatchedGroupedCiphertext2HandlesValidityProof, }, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodDecryptHandle, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs index 9a4252a..3b562eb 100644 --- a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs @@ -158,16 +158,13 @@ mod test { use { super::*, crate::{ - encryption::{ - elgamal::ElGamalKeypair, - pedersen::Pedersen, - pod::{ - elgamal::{PodDecryptHandle, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - }, + encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, sigma_proofs::pod::PodBatchedGroupedCiphertext3HandlesValidityProof, }, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodDecryptHandle, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs index 96e3e29..29c1453 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs @@ -278,10 +278,8 @@ impl CiphertextCiphertextEqualityProof { mod test { use { super::*, - crate::{ - encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, - }, + crate::sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs index b9bab3a..e951e7c 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs @@ -255,16 +255,13 @@ mod test { use { super::*, crate::{ - encryption::{ - elgamal::ElGamalSecretKey, - pedersen::Pedersen, - pod::{ - elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - }, + encryption::{elgamal::ElGamalSecretKey, pedersen::Pedersen}, sigma_proofs::pod::PodCiphertextCommitmentEqualityProof, }, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs index df429aa..e341869 100644 --- a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs @@ -248,16 +248,13 @@ mod test { use { super::*, crate::{ - encryption::{ - elgamal::ElGamalKeypair, - pedersen::Pedersen, - pod::{ - elgamal::{PodDecryptHandle, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - }, + encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, sigma_proofs::pod::PodGroupedCiphertext2HandlesValidityProof, }, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodDecryptHandle, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs index 7ad2512..1beab42 100644 --- a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs @@ -279,16 +279,13 @@ mod test { use { super::*, crate::{ - encryption::{ - elgamal::ElGamalKeypair, - pedersen::Pedersen, - pod::{ - elgamal::{PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - }, + encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, sigma_proofs::pod::PodGroupedCiphertext3HandlesValidityProof, }, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs index aa75401..d30be4f 100644 --- a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs +++ b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs @@ -612,10 +612,8 @@ fn conditional_select_ristretto( mod test { use { super::*, - crate::{ - encryption::{pedersen::Pedersen, pod::pedersen::PodPedersenCommitment}, - sigma_proofs::pod::PodPercentageWithCapProof, - }, + crate::{encryption::pedersen::Pedersen, sigma_proofs::pod::PodPercentageWithCapProof}, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/pubkey_validity.rs b/zk-sdk/src/sigma_proofs/pubkey_validity.rs index 948204e..257c99c 100644 --- a/zk-sdk/src/sigma_proofs/pubkey_validity.rs +++ b/zk-sdk/src/sigma_proofs/pubkey_validity.rs @@ -146,15 +146,9 @@ impl PubkeyValidityProof { #[cfg(test)] mod test { use { - super::*, - crate::{ - encryption::pod::elgamal::PodElGamalPubkey, sigma_proofs::pod::PodPubkeyValidityProof, - }, - bytemuck::Zeroable, - curve25519_dalek::traits::Identity, - solana_keypair::Keypair, - solana_pubkey::Pubkey, - std::str::FromStr, + super::*, crate::sigma_proofs::pod::PodPubkeyValidityProof, bytemuck::Zeroable, + curve25519_dalek::traits::Identity, solana_keypair::Keypair, solana_pubkey::Pubkey, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, std::str::FromStr, }; #[test] diff --git a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs index 1932459..4a34136 100644 --- a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs +++ b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs @@ -185,10 +185,10 @@ mod test { encryption::{ elgamal::{DecryptHandle, ElGamalKeypair}, pedersen::{Pedersen, PedersenCommitment, PedersenOpening}, - pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, }, sigma_proofs::pod::PodZeroCiphertextProof, }, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::str::FromStr, }; diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index e648a96..e04af48 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -5,16 +5,6 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. -use { - crate::{ - encryption::pod::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, - }, - sigma_proofs::pod::PodBatchedGroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -28,6 +18,16 @@ use { bytemuck::bytes_of, merlin::Transcript, }; +use { + crate::{ + sigma_proofs::pod::PodBatchedGroupedCiphertext2HandlesValidityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, +}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedGroupedCiphertextValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs index aee6e6f..557a422 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -5,16 +5,6 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. -use { - crate::{ - encryption::pod::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, - }, - sigma_proofs::pod::PodBatchedGroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -28,6 +18,16 @@ use { bytemuck::bytes_of, merlin::Transcript, }; +use { + crate::{ + sigma_proofs::pod::PodBatchedGroupedCiphertext3HandlesValidityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, +}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs index a003a21..0c6cbcd 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs @@ -21,7 +21,7 @@ pub mod batched_range_proof_u128; pub mod batched_range_proof_u256; pub mod batched_range_proof_u64; -use crate::encryption::pod::pedersen::PodPedersenCommitment; +use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; #[cfg(not(target_os = "solana"))] use { crate::{ diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs index 21437bd..90bff04 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs @@ -5,14 +5,6 @@ //! the proof, a prover must provide the decryption key for the first ciphertext and the randomness //! used to generate the second ciphertext. -use { - crate::{ - encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -27,6 +19,14 @@ use { merlin::Transcript, std::convert::TryInto, }; +use { + crate::{ + sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, +}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs index bb09343..524f563 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs @@ -5,17 +5,6 @@ //! encrypts/encodes the same message. To generate the proof, a prover must provide the decryption //! key for the first ciphertext and the Pedersen opening for the commitment. -use { - crate::{ - encryption::pod::{ - elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - sigma_proofs::pod::PodCiphertextCommitmentEqualityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -30,6 +19,17 @@ use { merlin::Transcript, std::convert::TryInto, }; +use { + crate::{ + sigma_proofs::pod::PodCiphertextCommitmentEqualityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, +}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction. /// diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs index df0668b..3410f13 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -5,16 +5,6 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. -use { - crate::{ - encryption::pod::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, - }, - sigma_proofs::pod::PodGroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -28,6 +18,16 @@ use { bytemuck::bytes_of, merlin::Transcript, }; +use { + crate::{ + sigma_proofs::pod::PodGroupedCiphertext2HandlesValidityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, +}; /// The instruction data that is needed for the `ProofInstruction::VerifyGroupedCiphertextValidity` /// instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs index 1ceaa17..d8815c1 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -5,16 +5,6 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. -use { - crate::{ - encryption::pod::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, - }, - sigma_proofs::pod::PodGroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -28,6 +18,16 @@ use { bytemuck::bytes_of, merlin::Transcript, }; +use { + crate::{ + sigma_proofs::pod::PodGroupedCiphertext3HandlesValidityProof, + zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, +}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyGroupedCiphertext3HandlesValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs index 9c62eaf..2445bfb 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs @@ -19,12 +19,12 @@ use { }; use { crate::{ - encryption::pod::pedersen::PodPedersenCommitment, pod::PodU64, sigma_proofs::pod::PodPercentageWithCapProof, zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, }, bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, }; /// The instruction data that is needed for the `ProofInstruction::VerifyPercentageWithCap` diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs index 8b8ceb9..7749705 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs @@ -18,11 +18,11 @@ use { }; use { crate::{ - encryption::pod::elgamal::PodElGamalPubkey, sigma_proofs::pod::PodPubkeyValidityProof, zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, }, bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, }; /// The instruction data that is needed for the `ProofInstruction::VerifyPubkeyValidity` diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs index 4da673b..0cab726 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs @@ -17,11 +17,11 @@ use { }; use { crate::{ - encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, sigma_proofs::pod::PodZeroCiphertextProof, zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, }, bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, }; /// The instruction data that is needed for the `ProofInstruction::VerifyZeroCiphertext` instruction. From 675254859eb0054ef91641d97beca172f1569b06 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Fri, 17 Oct 2025 14:12:34 +0900 Subject: [PATCH 2/7] clean up pod encryption types in zk-sdk --- zk-sdk/src/encryption/auth_encryption.rs | 30 ++++- zk-sdk/src/encryption/elgamal.rs | 81 ++++++++++- zk-sdk/src/encryption/grouped_elgamal.rs | 125 ++++++++++++++++- zk-sdk/src/encryption/pedersen.rs | 22 ++- zk-sdk/src/encryption/pod/auth_encryption.rs | 36 +---- zk-sdk/src/encryption/pod/elgamal.rs | 104 +------------- zk-sdk/src/encryption/pod/grouped_elgamal.rs | 135 +------------------ zk-sdk/src/encryption/pod/pedersen.rs | 31 +---- 8 files changed, 258 insertions(+), 306 deletions(-) diff --git a/zk-sdk/src/encryption/auth_encryption.rs b/zk-sdk/src/encryption/auth_encryption.rs index f409b01..5218979 100644 --- a/zk-sdk/src/encryption/auth_encryption.rs +++ b/zk-sdk/src/encryption/auth_encryption.rs @@ -20,6 +20,7 @@ use { solana_seed_phrase::generate_seed_from_seed_phrase_and_passphrase, solana_signature::Signature, solana_signer::{EncodableKey, Signer, SignerError}, + solana_zk_sdk_pod::encryption::auth_encryption::PodAeCiphertext, std::{ convert::TryInto, error, fmt, @@ -279,11 +280,27 @@ impl fmt::Display for AeCiphertext { } } +#[cfg(not(target_os = "solana"))] +impl From for PodAeCiphertext { + fn from(decoded_ciphertext: AeCiphertext) -> Self { + Self(decoded_ciphertext.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for AeCiphertext { + type Error = AuthenticatedEncryptionError; + + fn try_from(pod_ciphertext: PodAeCiphertext) -> Result { + Self::from_bytes(&pod_ciphertext.0).ok_or(AuthenticatedEncryptionError::Deserialization) + } +} + #[cfg(test)] mod tests { use { super::*, solana_keypair::Keypair, solana_pubkey::Pubkey, - solana_signer::null_signer::NullSigner, + solana_signer::null_signer::NullSigner, std::str::FromStr, }; #[test] @@ -392,4 +409,15 @@ mod tests { assert_ne!(ciphertext1.to_bytes(), ciphertext2.to_bytes()); } + + #[test] + fn ae_ciphertext_fromstr() { + let ae_key = AeKey::new_rand(); + let expected_ae_ciphertext: PodAeCiphertext = ae_key.encrypt(0_u64).into(); + + let ae_ciphertext_base64_str = format!("{}", expected_ae_ciphertext); + let computed_ae_ciphertext = PodAeCiphertext::from_str(&ae_ciphertext_base64_str).unwrap(); + + assert_eq!(expected_ae_ciphertext, computed_ae_ciphertext); + } } diff --git a/zk-sdk/src/encryption/elgamal.rs b/zk-sdk/src/encryption/elgamal.rs index 93e0cc6..4ac7c3f 100644 --- a/zk-sdk/src/encryption/elgamal.rs +++ b/zk-sdk/src/encryption/elgamal.rs @@ -39,6 +39,9 @@ use { solana_seed_phrase::generate_seed_from_seed_phrase_and_passphrase, solana_signature::Signature, solana_signer::{EncodableKey, EncodableKeypair, Signer, SignerError}, + solana_zk_sdk_pod::encryption::elgamal::{ + PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey, + }, std::{ convert::TryInto, error, fmt, @@ -442,6 +445,22 @@ impl From<&ElGamalPubkey> for [u8; ELGAMAL_PUBKEY_LEN] { } } +#[cfg(not(target_os = "solana"))] +impl From for PodElGamalPubkey { + fn from(decoded_pubkey: ElGamalPubkey) -> Self { + Self(decoded_pubkey.into()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for ElGamalPubkey { + type Error = ElGamalError; + + fn try_from(pod_pubkey: PodElGamalPubkey) -> Result { + Self::try_from(pod_pubkey.0.as_slice()) + } +} + /// Secret key for the ElGamal encryption scheme. /// /// Instances of ElGamal secret key are zeroized on drop. @@ -708,6 +727,22 @@ impl fmt::Display for ElGamalCiphertext { } } +#[cfg(not(target_os = "solana"))] +impl From for PodElGamalCiphertext { + fn from(decoded_ciphertext: ElGamalCiphertext) -> Self { + Self(decoded_ciphertext.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for ElGamalCiphertext { + type Error = ElGamalError; + + fn try_from(pod_ciphertext: PodElGamalCiphertext) -> Result { + Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) + } +} + impl<'b> Add<&'b ElGamalCiphertext> for &ElGamalCiphertext { type Output = ElGamalCiphertext; @@ -804,6 +839,22 @@ impl DecryptHandle { } } +#[cfg(not(target_os = "solana"))] +impl From for PodDecryptHandle { + fn from(decoded_handle: DecryptHandle) -> Self { + Self(decoded_handle.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for DecryptHandle { + type Error = ElGamalError; + + fn try_from(pod_handle: PodDecryptHandle) -> Result { + Self::from_bytes(&pod_handle.0).ok_or(ElGamalError::CiphertextDeserialization) + } +} + impl<'b> Add<&'b DecryptHandle> for &DecryptHandle { type Output = DecryptHandle; @@ -861,7 +912,10 @@ mod tests { solana_keypair::Keypair, solana_pubkey::Pubkey, solana_signer::null_signer::NullSigner, - std::fs::{self, File}, + std::{ + fs::{self, File}, + str::FromStr, + }, }; #[test] @@ -1234,4 +1288,29 @@ mod tests { Err(ElGamalError::SecretKeyDeserialization) )); } + + #[test] + fn elgamal_pubkey_fromstr() { + let elgamal_keypair = ElGamalKeypair::new_rand(); + let expected_elgamal_pubkey: PodElGamalPubkey = (*elgamal_keypair.pubkey()).into(); + + let elgamal_pubkey_base64_str = format!("{}", expected_elgamal_pubkey); + let computed_elgamal_pubkey = + PodElGamalPubkey::from_str(&elgamal_pubkey_base64_str).unwrap(); + + assert_eq!(expected_elgamal_pubkey, computed_elgamal_pubkey); + } + + #[test] + fn elgamal_ciphertext_fromstr() { + let elgamal_keypair = ElGamalKeypair::new_rand(); + let expected_elgamal_ciphertext: PodElGamalCiphertext = + elgamal_keypair.pubkey().encrypt(0_u64).into(); + + let elgamal_ciphertext_base64_str = format!("{}", expected_elgamal_ciphertext); + let computed_elgamal_ciphertext = + PodElGamalCiphertext::from_str(&elgamal_ciphertext_base64_str).unwrap(); + + assert_eq!(expected_elgamal_ciphertext, computed_elgamal_ciphertext); + } } diff --git a/zk-sdk/src/encryption/grouped_elgamal.rs b/zk-sdk/src/encryption/grouped_elgamal.rs index f4c2457..d0e93a2 100644 --- a/zk-sdk/src/encryption/grouped_elgamal.rs +++ b/zk-sdk/src/encryption/grouped_elgamal.rs @@ -19,9 +19,13 @@ use { elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey, ElGamalSecretKey}, pedersen::{Pedersen, PedersenCommitment, PedersenOpening}, }, + errors::ElGamalError, RISTRETTO_POINT_LEN, }, curve25519_dalek::scalar::Scalar, + solana_zk_sdk_pod::encryption::grouped_elgamal::{ + PodGroupedElGamalCiphertext2Handles, PodGroupedElGamalCiphertext3Handles, + }, thiserror::Error, }; @@ -217,9 +221,48 @@ impl GroupedElGamalCiphertext { } } +#[cfg(not(target_os = "solana"))] +impl From> for PodGroupedElGamalCiphertext2Handles { + fn from(decoded_ciphertext: GroupedElGamalCiphertext<2>) -> Self { + Self(decoded_ciphertext.to_bytes().try_into().unwrap()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for GroupedElGamalCiphertext<2> { + type Error = ElGamalError; + + fn try_from(pod_ciphertext: PodGroupedElGamalCiphertext2Handles) -> Result { + Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) + } +} + +#[cfg(not(target_os = "solana"))] +impl From> for PodGroupedElGamalCiphertext3Handles { + fn from(decoded_ciphertext: GroupedElGamalCiphertext<3>) -> Self { + Self(decoded_ciphertext.to_bytes().try_into().unwrap()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for GroupedElGamalCiphertext<3> { + type Error = ElGamalError; + + fn try_from(pod_ciphertext: PodGroupedElGamalCiphertext3Handles) -> Result { + Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) + } +} + #[cfg(test)] mod tests { - use {super::*, crate::encryption::elgamal::ElGamalKeypair}; + use { + super::*, + crate::encryption::elgamal::ElGamalKeypair, + solana_zk_sdk_pod::{ + encryption::{elgamal::PodElGamalCiphertext, pedersen::PodPedersenCommitment}, + errors::PodParseError, + }, + }; #[test] fn test_grouped_elgamal_encrypt_decrypt_correctness() { @@ -374,4 +417,84 @@ mod tests { bytes[32] = 1; assert!(GroupedElGamalCiphertext::<1>::from_bytes(&bytes).is_none()); } + + #[test] + fn test_2_handles_ciphertext_extraction() { + let elgamal_keypair_0 = ElGamalKeypair::new_rand(); + let elgamal_keypair_1 = ElGamalKeypair::new_rand(); + + let amount: u64 = 10; + let (commitment, opening) = Pedersen::new(amount); + + let grouped_ciphertext = GroupedElGamal::encrypt_with( + [elgamal_keypair_0.pubkey(), elgamal_keypair_1.pubkey()], + amount, + &opening, + ); + let pod_grouped_ciphertext: PodGroupedElGamalCiphertext2Handles = grouped_ciphertext.into(); + + let expected_pod_commitment: PodPedersenCommitment = commitment.into(); + let actual_pod_commitment = pod_grouped_ciphertext.extract_commitment(); + assert_eq!(expected_pod_commitment, actual_pod_commitment); + + let expected_ciphertext_0 = elgamal_keypair_0.pubkey().encrypt_with(amount, &opening); + let expected_pod_ciphertext_0: PodElGamalCiphertext = expected_ciphertext_0.into(); + let actual_pod_ciphertext_0 = pod_grouped_ciphertext.try_extract_ciphertext(0).unwrap(); + assert_eq!(expected_pod_ciphertext_0, actual_pod_ciphertext_0); + + let expected_ciphertext_1 = elgamal_keypair_1.pubkey().encrypt_with(amount, &opening); + let expected_pod_ciphertext_1: PodElGamalCiphertext = expected_ciphertext_1.into(); + let actual_pod_ciphertext_1 = pod_grouped_ciphertext.try_extract_ciphertext(1).unwrap(); + assert_eq!(expected_pod_ciphertext_1, actual_pod_ciphertext_1); + + let err = pod_grouped_ciphertext + .try_extract_ciphertext(2) + .unwrap_err(); + assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); + } + + #[test] + fn test_3_handles_ciphertext_extraction() { + let elgamal_keypair_0 = ElGamalKeypair::new_rand(); + let elgamal_keypair_1 = ElGamalKeypair::new_rand(); + let elgamal_keypair_2 = ElGamalKeypair::new_rand(); + + let amount: u64 = 10; + let (commitment, opening) = Pedersen::new(amount); + + let grouped_ciphertext = GroupedElGamal::encrypt_with( + [ + elgamal_keypair_0.pubkey(), + elgamal_keypair_1.pubkey(), + elgamal_keypair_2.pubkey(), + ], + amount, + &opening, + ); + let pod_grouped_ciphertext: PodGroupedElGamalCiphertext3Handles = grouped_ciphertext.into(); + + let expected_pod_commitment: PodPedersenCommitment = commitment.into(); + let actual_pod_commitment = pod_grouped_ciphertext.extract_commitment(); + assert_eq!(expected_pod_commitment, actual_pod_commitment); + + let expected_ciphertext_0 = elgamal_keypair_0.pubkey().encrypt_with(amount, &opening); + let expected_pod_ciphertext_0: PodElGamalCiphertext = expected_ciphertext_0.into(); + let actual_pod_ciphertext_0 = pod_grouped_ciphertext.try_extract_ciphertext(0).unwrap(); + assert_eq!(expected_pod_ciphertext_0, actual_pod_ciphertext_0); + + let expected_ciphertext_1 = elgamal_keypair_1.pubkey().encrypt_with(amount, &opening); + let expected_pod_ciphertext_1: PodElGamalCiphertext = expected_ciphertext_1.into(); + let actual_pod_ciphertext_1 = pod_grouped_ciphertext.try_extract_ciphertext(1).unwrap(); + assert_eq!(expected_pod_ciphertext_1, actual_pod_ciphertext_1); + + let expected_ciphertext_2 = elgamal_keypair_2.pubkey().encrypt_with(amount, &opening); + let expected_pod_ciphertext_2: PodElGamalCiphertext = expected_ciphertext_2.into(); + let actual_pod_ciphertext_2 = pod_grouped_ciphertext.try_extract_ciphertext(2).unwrap(); + assert_eq!(expected_pod_ciphertext_2, actual_pod_ciphertext_2); + + let err = pod_grouped_ciphertext + .try_extract_ciphertext(3) + .unwrap_err(); + assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); + } } diff --git a/zk-sdk/src/encryption/pedersen.rs b/zk-sdk/src/encryption/pedersen.rs index 6d52596..34e468a 100644 --- a/zk-sdk/src/encryption/pedersen.rs +++ b/zk-sdk/src/encryption/pedersen.rs @@ -1,7 +1,10 @@ //! Pedersen commitment implementation using the Ristretto prime-order group. use { - crate::encryption::{PEDERSEN_COMMITMENT_LEN, PEDERSEN_OPENING_LEN}, + crate::{ + encryption::{PEDERSEN_COMMITMENT_LEN, PEDERSEN_OPENING_LEN}, + errors::ElGamalError, + }, core::ops::{Add, Mul, Sub}, curve25519_dalek::{ constants::{RISTRETTO_BASEPOINT_COMPRESSED, RISTRETTO_BASEPOINT_POINT}, @@ -12,6 +15,7 @@ use { rand::rngs::OsRng, serde::{Deserialize, Serialize}, sha3::Sha3_512, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::{convert::TryInto, fmt}, subtle::{Choice, ConstantTimeEq}, zeroize::Zeroize, @@ -216,6 +220,22 @@ impl PedersenCommitment { } } +#[cfg(not(target_os = "solana"))] +impl From for PodPedersenCommitment { + fn from(decoded_commitment: PedersenCommitment) -> Self { + Self(decoded_commitment.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PedersenCommitment { + type Error = ElGamalError; + + fn try_from(pod_commitment: PodPedersenCommitment) -> Result { + Self::from_bytes(&pod_commitment.0).ok_or(ElGamalError::CiphertextDeserialization) + } +} + impl<'b> Add<&'b PedersenCommitment> for &PedersenCommitment { type Output = PedersenCommitment; diff --git a/zk-sdk/src/encryption/pod/auth_encryption.rs b/zk-sdk/src/encryption/pod/auth_encryption.rs index a97a408..e1d2336 100644 --- a/zk-sdk/src/encryption/pod/auth_encryption.rs +++ b/zk-sdk/src/encryption/pod/auth_encryption.rs @@ -1,37 +1,3 @@ //! Plain Old Data types for the AES128-GCM-SIV authenticated encryption scheme. -#[cfg(not(target_os = "solana"))] -use crate::{encryption::auth_encryption::AeCiphertext, errors::AuthenticatedEncryptionError}; -use solana_zk_sdk_pod::encryption::auth_encryption::PodAeCiphertext; - -#[cfg(not(target_os = "solana"))] -impl From for PodAeCiphertext { - fn from(decoded_ciphertext: AeCiphertext) -> Self { - Self(decoded_ciphertext.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for AeCiphertext { - type Error = AuthenticatedEncryptionError; - - fn try_from(pod_ciphertext: PodAeCiphertext) -> Result { - Self::from_bytes(&pod_ciphertext.0).ok_or(AuthenticatedEncryptionError::Deserialization) - } -} - -#[cfg(test)] -mod tests { - use {super::*, crate::encryption::auth_encryption::AeKey, std::str::FromStr}; - - #[test] - fn ae_ciphertext_fromstr() { - let ae_key = AeKey::new_rand(); - let expected_ae_ciphertext: PodAeCiphertext = ae_key.encrypt(0_u64).into(); - - let ae_ciphertext_base64_str = format!("{}", expected_ae_ciphertext); - let computed_ae_ciphertext = PodAeCiphertext::from_str(&ae_ciphertext_base64_str).unwrap(); - - assert_eq!(expected_ae_ciphertext, computed_ae_ciphertext); - } -} +pub use solana_zk_sdk_pod::encryption::auth_encryption::*; diff --git a/zk-sdk/src/encryption/pod/elgamal.rs b/zk-sdk/src/encryption/pod/elgamal.rs index 5737dbc..c21d5d1 100644 --- a/zk-sdk/src/encryption/pod/elgamal.rs +++ b/zk-sdk/src/encryption/pod/elgamal.rs @@ -1,105 +1,3 @@ //! Plain Old Data types for the ElGamal encryption scheme. -use solana_zk_sdk_pod::encryption::elgamal::{ - PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey, -}; -#[cfg(not(target_os = "solana"))] -use { - crate::{ - encryption::elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey}, - errors::ElGamalError, - }, - // curve25519_dalek::ristretto::CompressedRistretto, -}; - -#[cfg(not(target_os = "solana"))] -impl From for PodElGamalCiphertext { - fn from(decoded_ciphertext: ElGamalCiphertext) -> Self { - Self(decoded_ciphertext.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for ElGamalCiphertext { - type Error = ElGamalError; - - fn try_from(pod_ciphertext: PodElGamalCiphertext) -> Result { - Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) - } -} - -#[cfg(not(target_os = "solana"))] -impl From for PodElGamalPubkey { - fn from(decoded_pubkey: ElGamalPubkey) -> Self { - Self(decoded_pubkey.into()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for ElGamalPubkey { - type Error = ElGamalError; - - fn try_from(pod_pubkey: PodElGamalPubkey) -> Result { - Self::try_from(pod_pubkey.0.as_slice()) - } -} - -#[cfg(not(target_os = "solana"))] -impl From for PodDecryptHandle { - fn from(decoded_handle: DecryptHandle) -> Self { - Self(decoded_handle.to_bytes()) - } -} - -// // For proof verification, interpret pod::DecryptHandle as CompressedRistretto -// #[cfg(not(target_os = "solana"))] -// impl From for CompressedRistretto { -// fn from(pod_handle: PodDecryptHandle) -> Self { -// Self(pod_handle.0) -// } -// } - -#[cfg(not(target_os = "solana"))] -impl TryFrom for DecryptHandle { - type Error = ElGamalError; - - fn try_from(pod_handle: PodDecryptHandle) -> Result { - Self::from_bytes(&pod_handle.0).ok_or(ElGamalError::CiphertextDeserialization) - } -} - -// impl fmt::Display for PodDecryptHandle { -// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// write!(f, "{}", BASE64_STANDARD.encode(self.0)) -// } -// } - -#[cfg(test)] -mod tests { - use {super::*, crate::encryption::elgamal::ElGamalKeypair, std::str::FromStr}; - - #[test] - fn elgamal_pubkey_fromstr() { - let elgamal_keypair = ElGamalKeypair::new_rand(); - let expected_elgamal_pubkey: PodElGamalPubkey = (*elgamal_keypair.pubkey()).into(); - - let elgamal_pubkey_base64_str = format!("{}", expected_elgamal_pubkey); - let computed_elgamal_pubkey = - PodElGamalPubkey::from_str(&elgamal_pubkey_base64_str).unwrap(); - - assert_eq!(expected_elgamal_pubkey, computed_elgamal_pubkey); - } - - #[test] - fn elgamal_ciphertext_fromstr() { - let elgamal_keypair = ElGamalKeypair::new_rand(); - let expected_elgamal_ciphertext: PodElGamalCiphertext = - elgamal_keypair.pubkey().encrypt(0_u64).into(); - - let elgamal_ciphertext_base64_str = format!("{}", expected_elgamal_ciphertext); - let computed_elgamal_ciphertext = - PodElGamalCiphertext::from_str(&elgamal_ciphertext_base64_str).unwrap(); - - assert_eq!(expected_elgamal_ciphertext, computed_elgamal_ciphertext); - } -} +pub use solana_zk_sdk_pod::encryption::elgamal::*; diff --git a/zk-sdk/src/encryption/pod/grouped_elgamal.rs b/zk-sdk/src/encryption/pod/grouped_elgamal.rs index e2e588e..0c08b70 100644 --- a/zk-sdk/src/encryption/pod/grouped_elgamal.rs +++ b/zk-sdk/src/encryption/pod/grouped_elgamal.rs @@ -1,136 +1,3 @@ //! Plain Old Data types for the Grouped ElGamal encryption scheme. -#[cfg(not(target_os = "solana"))] -use crate::encryption::grouped_elgamal::GroupedElGamalCiphertext; -use { - crate::errors::ElGamalError, - solana_zk_sdk_pod::encryption::grouped_elgamal::{ - PodGroupedElGamalCiphertext2Handles, PodGroupedElGamalCiphertext3Handles, - }, -}; - -#[cfg(not(target_os = "solana"))] -impl From> for PodGroupedElGamalCiphertext2Handles { - fn from(decoded_ciphertext: GroupedElGamalCiphertext<2>) -> Self { - Self(decoded_ciphertext.to_bytes().try_into().unwrap()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for GroupedElGamalCiphertext<2> { - type Error = ElGamalError; - - fn try_from(pod_ciphertext: PodGroupedElGamalCiphertext2Handles) -> Result { - Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) - } -} - -#[cfg(not(target_os = "solana"))] -impl From> for PodGroupedElGamalCiphertext3Handles { - fn from(decoded_ciphertext: GroupedElGamalCiphertext<3>) -> Self { - Self(decoded_ciphertext.to_bytes().try_into().unwrap()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for GroupedElGamalCiphertext<3> { - type Error = ElGamalError; - - fn try_from(pod_ciphertext: PodGroupedElGamalCiphertext3Handles) -> Result { - Self::from_bytes(&pod_ciphertext.0).ok_or(ElGamalError::CiphertextDeserialization) - } -} - -#[cfg(test)] -mod tests { - use { - super::*, - crate::encryption::{ - elgamal::ElGamalKeypair, grouped_elgamal::GroupedElGamal, pedersen::Pedersen, - }, - solana_zk_sdk_pod::{ - encryption::{elgamal::PodElGamalCiphertext, pedersen::PodPedersenCommitment}, - errors::PodParseError, - }, - }; - - #[test] - fn test_2_handles_ciphertext_extraction() { - let elgamal_keypair_0 = ElGamalKeypair::new_rand(); - let elgamal_keypair_1 = ElGamalKeypair::new_rand(); - - let amount: u64 = 10; - let (commitment, opening) = Pedersen::new(amount); - - let grouped_ciphertext = GroupedElGamal::encrypt_with( - [elgamal_keypair_0.pubkey(), elgamal_keypair_1.pubkey()], - amount, - &opening, - ); - let pod_grouped_ciphertext: PodGroupedElGamalCiphertext2Handles = grouped_ciphertext.into(); - - let expected_pod_commitment: PodPedersenCommitment = commitment.into(); - let actual_pod_commitment = pod_grouped_ciphertext.extract_commitment(); - assert_eq!(expected_pod_commitment, actual_pod_commitment); - - let expected_ciphertext_0 = elgamal_keypair_0.pubkey().encrypt_with(amount, &opening); - let expected_pod_ciphertext_0: PodElGamalCiphertext = expected_ciphertext_0.into(); - let actual_pod_ciphertext_0 = pod_grouped_ciphertext.try_extract_ciphertext(0).unwrap(); - assert_eq!(expected_pod_ciphertext_0, actual_pod_ciphertext_0); - - let expected_ciphertext_1 = elgamal_keypair_1.pubkey().encrypt_with(amount, &opening); - let expected_pod_ciphertext_1: PodElGamalCiphertext = expected_ciphertext_1.into(); - let actual_pod_ciphertext_1 = pod_grouped_ciphertext.try_extract_ciphertext(1).unwrap(); - assert_eq!(expected_pod_ciphertext_1, actual_pod_ciphertext_1); - - let err = pod_grouped_ciphertext - .try_extract_ciphertext(2) - .unwrap_err(); - assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); - } - - #[test] - fn test_3_handles_ciphertext_extraction() { - let elgamal_keypair_0 = ElGamalKeypair::new_rand(); - let elgamal_keypair_1 = ElGamalKeypair::new_rand(); - let elgamal_keypair_2 = ElGamalKeypair::new_rand(); - - let amount: u64 = 10; - let (commitment, opening) = Pedersen::new(amount); - - let grouped_ciphertext = GroupedElGamal::encrypt_with( - [ - elgamal_keypair_0.pubkey(), - elgamal_keypair_1.pubkey(), - elgamal_keypair_2.pubkey(), - ], - amount, - &opening, - ); - let pod_grouped_ciphertext: PodGroupedElGamalCiphertext3Handles = grouped_ciphertext.into(); - - let expected_pod_commitment: PodPedersenCommitment = commitment.into(); - let actual_pod_commitment = pod_grouped_ciphertext.extract_commitment(); - assert_eq!(expected_pod_commitment, actual_pod_commitment); - - let expected_ciphertext_0 = elgamal_keypair_0.pubkey().encrypt_with(amount, &opening); - let expected_pod_ciphertext_0: PodElGamalCiphertext = expected_ciphertext_0.into(); - let actual_pod_ciphertext_0 = pod_grouped_ciphertext.try_extract_ciphertext(0).unwrap(); - assert_eq!(expected_pod_ciphertext_0, actual_pod_ciphertext_0); - - let expected_ciphertext_1 = elgamal_keypair_1.pubkey().encrypt_with(amount, &opening); - let expected_pod_ciphertext_1: PodElGamalCiphertext = expected_ciphertext_1.into(); - let actual_pod_ciphertext_1 = pod_grouped_ciphertext.try_extract_ciphertext(1).unwrap(); - assert_eq!(expected_pod_ciphertext_1, actual_pod_ciphertext_1); - - let expected_ciphertext_2 = elgamal_keypair_2.pubkey().encrypt_with(amount, &opening); - let expected_pod_ciphertext_2: PodElGamalCiphertext = expected_ciphertext_2.into(); - let actual_pod_ciphertext_2 = pod_grouped_ciphertext.try_extract_ciphertext(2).unwrap(); - assert_eq!(expected_pod_ciphertext_2, actual_pod_ciphertext_2); - - let err = pod_grouped_ciphertext - .try_extract_ciphertext(3) - .unwrap_err(); - assert_eq!(err, PodParseError::GroupedCiphertextIndexOutOfBounds); - } -} +pub use solana_zk_sdk_pod::encryption::grouped_elgamal::*; diff --git a/zk-sdk/src/encryption/pod/pedersen.rs b/zk-sdk/src/encryption/pod/pedersen.rs index 484da2c..feedcb6 100644 --- a/zk-sdk/src/encryption/pod/pedersen.rs +++ b/zk-sdk/src/encryption/pod/pedersen.rs @@ -1,32 +1,3 @@ //! Plain Old Data type for the Pedersen commitment scheme. -use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; -#[cfg(not(target_os = "solana"))] -use { - crate::{encryption::pedersen::PedersenCommitment, errors::ElGamalError}, - // curve25519_dalek::ristretto::CompressedRistretto, -}; - -#[cfg(not(target_os = "solana"))] -impl From for PodPedersenCommitment { - fn from(decoded_commitment: PedersenCommitment) -> Self { - Self(decoded_commitment.to_bytes()) - } -} - -// // For proof verification, interpret pod::PedersenCommitment directly as CompressedRistretto -// #[cfg(not(target_os = "solana"))] -// impl From for CompressedRistretto { -// fn from(pod_commitment: PodPedersenCommitment) -> Self { -// Self(pod_commitment.0) -// } -// } - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PedersenCommitment { - type Error = ElGamalError; - - fn try_from(pod_commitment: PodPedersenCommitment) -> Result { - Self::from_bytes(&pod_commitment.0).ok_or(ElGamalError::CiphertextDeserialization) - } -} +pub use solana_zk_sdk_pod::encryption::pedersen::*; From 835bc7ebd15e250273457cef485a95f3d585530f Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Sun, 26 Oct 2025 18:14:21 +0900 Subject: [PATCH 3/7] migrate sigma proof pod types --- zk-sdk-pod/src/lib.rs | 1 + .../pod.rs => zk-sdk-pod/src/sigma_proofs.rs | 225 +++--------------- .../handles_2.rs | 28 ++- .../handles_3.rs | 28 ++- .../ciphertext_ciphertext_equality.rs | 18 +- .../ciphertext_commitment_equality.rs | 22 +- .../grouped_ciphertext_validity/handles_2.rs | 22 +- .../grouped_ciphertext_validity/handles_3.rs | 22 +- zk-sdk/src/sigma_proofs/mod.rs | 35 +-- .../src/sigma_proofs/percentage_with_cap.rs | 23 +- zk-sdk/src/sigma_proofs/pubkey_validity.rs | 23 +- zk-sdk/src/sigma_proofs/zero_ciphertext.rs | 26 +- .../handles_2.rs | 20 +- .../handles_3.rs | 20 +- .../ciphertext_ciphertext_equality.rs | 16 +- .../ciphertext_commitment_equality.rs | 22 +- .../grouped_ciphertext_validity/handles_2.rs | 20 +- .../grouped_ciphertext_validity/handles_3.rs | 20 +- .../proof_data/percentage_with_cap.rs | 5 +- .../proof_data/pubkey_validity.rs | 15 +- .../proof_data/zero_ciphertext.rs | 16 +- 21 files changed, 301 insertions(+), 326 deletions(-) rename zk-sdk/src/sigma_proofs/pod.rs => zk-sdk-pod/src/sigma_proofs.rs (54%) diff --git a/zk-sdk-pod/src/lib.rs b/zk-sdk-pod/src/lib.rs index a946c04..18db44c 100644 --- a/zk-sdk-pod/src/lib.rs +++ b/zk-sdk-pod/src/lib.rs @@ -1,6 +1,7 @@ pub mod encryption; pub mod errors; pub mod macros; +pub mod sigma_proofs; /// Byte length of a compressed Ristretto point or scalar in Curve255519 const UNIT_LEN: usize = 32; diff --git a/zk-sdk/src/sigma_proofs/pod.rs b/zk-sdk-pod/src/sigma_proofs.rs similarity index 54% rename from zk-sdk/src/sigma_proofs/pod.rs rename to zk-sdk-pod/src/sigma_proofs.rs index 3ce3f38..07ae754 100644 --- a/zk-sdk/src/sigma_proofs/pod.rs +++ b/zk-sdk-pod/src/sigma_proofs.rs @@ -1,52 +1,43 @@ //! Plain Old Data types for sigma proofs. -#[cfg(not(target_os = "solana"))] -use crate::sigma_proofs::{ - batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext2HandlesValidityProof, - BatchedGroupedCiphertext3HandlesValidityProof, - }, - ciphertext_ciphertext_equality::CiphertextCiphertextEqualityProof, - ciphertext_commitment_equality::CiphertextCommitmentEqualityProof, - grouped_ciphertext_validity::{ - GroupedCiphertext2HandlesValidityProof, GroupedCiphertext3HandlesValidityProof, - }, - percentage_with_cap::PercentageWithCapProof, - pubkey_validity::PubkeyValidityProof, - zero_ciphertext::ZeroCiphertextProof, -}; use { - crate::{ - pod::{impl_from_bytes, impl_from_str}, - sigma_proofs::{errors::*, *}, - }, + crate::macros::{impl_from_bytes, impl_from_str}, base64::{prelude::BASE64_STANDARD, Engine}, bytemuck::{Pod, Zeroable}, std::fmt, }; -/// The `CiphertextCommitmentEqualityProof` type as a `Pod`. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct PodCiphertextCommitmentEqualityProof( - pub(crate) [u8; CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN], -); +/// Byte length of a ciphertext-commitment equality proof +pub const CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN: usize = 192; -#[cfg(not(target_os = "solana"))] -impl From for PodCiphertextCommitmentEqualityProof { - fn from(decoded_proof: CiphertextCommitmentEqualityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} +/// Byte length of a ciphertext-ciphertext equality proof +pub const CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN: usize = 224; -#[cfg(not(target_os = "solana"))] -impl TryFrom for CiphertextCommitmentEqualityProof { - type Error = EqualityProofVerificationError; +/// Byte length of a grouped ciphertext for 2 handles validity proof +pub const GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN: usize = 160; - fn try_from(pod_proof: PodCiphertextCommitmentEqualityProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} +/// Byte length of a grouped ciphertext for 3 handles validity proof +pub const GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = 192; + +/// Byte length of a batched grouped ciphertext for 2 handles validity proof +pub const BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN: usize = 160; + +/// Byte length of a batched grouped ciphertext for 3 handles validity proof +pub const BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = 192; + +/// Byte length of a zero-ciphertext proof +pub const ZERO_CIPHERTEXT_PROOF_LEN: usize = 96; + +/// Byte length of a percentage with cap proof +pub const PERCENTAGE_WITH_CAP_PROOF_LEN: usize = 256; + +/// Byte length of a public key validity proof +pub const PUBKEY_VALIDITY_PROOF_LEN: usize = 64; + +/// The `CiphertextCommitmentEqualityProof` type as a `Pod`. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct PodCiphertextCommitmentEqualityProof(pub [u8; CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN]); const CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_MAX_BASE64_LEN: usize = 256; @@ -70,25 +61,7 @@ impl_from_bytes!( /// The `CiphertextCiphertextEqualityProof` type as a `Pod`. #[derive(Clone, Copy)] #[repr(transparent)] -pub struct PodCiphertextCiphertextEqualityProof( - pub(crate) [u8; CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN], -); - -#[cfg(not(target_os = "solana"))] -impl From for PodCiphertextCiphertextEqualityProof { - fn from(decoded_proof: CiphertextCiphertextEqualityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for CiphertextCiphertextEqualityProof { - type Error = EqualityProofVerificationError; - - fn try_from(pod_proof: PodCiphertextCiphertextEqualityProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} +pub struct PodCiphertextCiphertextEqualityProof(pub [u8; CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN]); const CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_MAX_BASE64_LEN: usize = 300; @@ -113,25 +86,9 @@ impl_from_bytes!( #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodGroupedCiphertext2HandlesValidityProof( - pub(crate) [u8; GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN], + pub [u8; GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN], ); -#[cfg(not(target_os = "solana"))] -impl From for PodGroupedCiphertext2HandlesValidityProof { - fn from(decoded_proof: GroupedCiphertext2HandlesValidityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for GroupedCiphertext2HandlesValidityProof { - type Error = ValidityProofVerificationError; - - fn try_from(pod_proof: PodGroupedCiphertext2HandlesValidityProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - const GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_MAX_BASE64_LEN: usize = 216; impl fmt::Display for PodGroupedCiphertext2HandlesValidityProof { @@ -155,25 +112,9 @@ impl_from_bytes!( #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodGroupedCiphertext3HandlesValidityProof( - pub(crate) [u8; GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN], + pub [u8; GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN], ); -#[cfg(not(target_os = "solana"))] -impl From for PodGroupedCiphertext3HandlesValidityProof { - fn from(decoded_proof: GroupedCiphertext3HandlesValidityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for GroupedCiphertext3HandlesValidityProof { - type Error = ValidityProofVerificationError; - - fn try_from(pod_proof: PodGroupedCiphertext3HandlesValidityProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - const GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_MAX_BASE64_LEN: usize = 256; impl fmt::Display for PodGroupedCiphertext3HandlesValidityProof { @@ -197,31 +138,9 @@ impl_from_bytes!( #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodBatchedGroupedCiphertext2HandlesValidityProof( - pub(crate) [u8; BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN], + pub [u8; BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN], ); -#[cfg(not(target_os = "solana"))] -impl From - for PodBatchedGroupedCiphertext2HandlesValidityProof -{ - fn from(decoded_proof: BatchedGroupedCiphertext2HandlesValidityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom - for BatchedGroupedCiphertext2HandlesValidityProof -{ - type Error = ValidityProofVerificationError; - - fn try_from( - pod_proof: PodBatchedGroupedCiphertext2HandlesValidityProof, - ) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - const BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_MAX_BASE64_LEN: usize = 216; impl fmt::Display for PodBatchedGroupedCiphertext2HandlesValidityProof { @@ -245,31 +164,9 @@ impl_from_bytes!( #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodBatchedGroupedCiphertext3HandlesValidityProof( - pub(crate) [u8; BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN], + pub [u8; BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN], ); -#[cfg(not(target_os = "solana"))] -impl From - for PodBatchedGroupedCiphertext3HandlesValidityProof -{ - fn from(decoded_proof: BatchedGroupedCiphertext3HandlesValidityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom - for BatchedGroupedCiphertext3HandlesValidityProof -{ - type Error = ValidityProofVerificationError; - - fn try_from( - pod_proof: PodBatchedGroupedCiphertext3HandlesValidityProof, - ) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - const BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_MAX_BASE64_LEN: usize = 256; impl fmt::Display for PodBatchedGroupedCiphertext3HandlesValidityProof { @@ -292,23 +189,7 @@ impl_from_bytes!( /// The `ZeroCiphertextProof` type as a `Pod`. #[derive(Clone, Copy)] #[repr(transparent)] -pub struct PodZeroCiphertextProof(pub(crate) [u8; ZERO_CIPHERTEXT_PROOF_LEN]); - -#[cfg(not(target_os = "solana"))] -impl From for PodZeroCiphertextProof { - fn from(decoded_proof: ZeroCiphertextProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for ZeroCiphertextProof { - type Error = ZeroCiphertextProofVerificationError; - - fn try_from(pod_proof: PodZeroCiphertextProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} +pub struct PodZeroCiphertextProof(pub [u8; ZERO_CIPHERTEXT_PROOF_LEN]); const ZERO_CIPHERTEXT_PROOF_MAX_BASE64_LEN: usize = 128; @@ -332,23 +213,7 @@ impl_from_bytes!( /// The `PercentageWithCapProof` type as a `Pod`. #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable)] #[repr(transparent)] -pub struct PodPercentageWithCapProof(pub(crate) [u8; PERCENTAGE_WITH_CAP_PROOF_LEN]); - -#[cfg(not(target_os = "solana"))] -impl From for PodPercentageWithCapProof { - fn from(decoded_proof: PercentageWithCapProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PercentageWithCapProof { - type Error = PercentageWithCapProofVerificationError; - - fn try_from(pod_proof: PodPercentageWithCapProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} +pub struct PodPercentageWithCapProof(pub [u8; PERCENTAGE_WITH_CAP_PROOF_LEN]); const PERCENTAGE_WITH_CAP_PROOF_MAX_BASE64_LEN: usize = 344; @@ -372,23 +237,7 @@ impl_from_bytes!( /// The `PubkeyValidityProof` type as a `Pod`. #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable)] #[repr(transparent)] -pub struct PodPubkeyValidityProof(pub(crate) [u8; PUBKEY_VALIDITY_PROOF_LEN]); - -#[cfg(not(target_os = "solana"))] -impl From for PodPubkeyValidityProof { - fn from(decoded_proof: PubkeyValidityProof) -> Self { - Self(decoded_proof.to_bytes()) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PubkeyValidityProof { - type Error = PubkeyValidityProofVerificationError; - - fn try_from(pod_proof: PodPubkeyValidityProof) -> Result { - Self::from_bytes(&pod_proof.0) - } -} +pub struct PodPubkeyValidityProof(pub [u8; PUBKEY_VALIDITY_PROOF_LEN]); const PUBKEY_VALIDITY_PROOF_MAX_BASE64_LEN: usize = 88; diff --git a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs index 19664bd..849b4b7 100644 --- a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_2.rs @@ -23,6 +23,7 @@ use { elgamal::{DecryptHandle, ElGamalPubkey}, pedersen::{PedersenCommitment, PedersenOpening}, }, + solana_zk_sdk_pod::sigma_proofs::PodBatchedGroupedCiphertext2HandlesValidityProof, zeroize::Zeroize, }; use { @@ -142,14 +143,33 @@ impl BatchedGroupedCiphertext2HandlesValidityProof { } } +#[cfg(not(target_os = "solana"))] +impl From + for PodBatchedGroupedCiphertext2HandlesValidityProof +{ + fn from(decoded_proof: BatchedGroupedCiphertext2HandlesValidityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom + for BatchedGroupedCiphertext2HandlesValidityProof +{ + type Error = ValidityProofVerificationError; + + fn try_from( + pod_proof: PodBatchedGroupedCiphertext2HandlesValidityProof, + ) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, - sigma_proofs::pod::PodBatchedGroupedCiphertext2HandlesValidityProof, - }, + crate::encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, solana_zk_sdk_pod::encryption::{ elgamal::{PodDecryptHandle, PodElGamalPubkey}, pedersen::PodPedersenCommitment, diff --git a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs index 3b562eb..8cf4b4e 100644 --- a/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/sigma_proofs/batched_grouped_ciphertext_validity/handles_3.rs @@ -27,6 +27,7 @@ use { elgamal::{DecryptHandle, ElGamalPubkey}, pedersen::{PedersenCommitment, PedersenOpening}, }, + solana_zk_sdk_pod::sigma_proofs::PodBatchedGroupedCiphertext3HandlesValidityProof, zeroize::Zeroize, }; use { @@ -153,14 +154,33 @@ impl BatchedGroupedCiphertext3HandlesValidityProof { } } +#[cfg(not(target_os = "solana"))] +impl From + for PodBatchedGroupedCiphertext3HandlesValidityProof +{ + fn from(decoded_proof: BatchedGroupedCiphertext3HandlesValidityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom + for BatchedGroupedCiphertext3HandlesValidityProof +{ + type Error = ValidityProofVerificationError; + + fn try_from( + pod_proof: PodBatchedGroupedCiphertext3HandlesValidityProof, + ) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, - sigma_proofs::pod::PodBatchedGroupedCiphertext3HandlesValidityProof, - }, + crate::encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, solana_zk_sdk_pod::encryption::{ elgamal::{PodDecryptHandle, PodElGamalPubkey}, pedersen::PodPedersenCommitment, diff --git a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs index 29c1453..d8358b1 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs @@ -15,6 +15,7 @@ use { }, curve25519_dalek::traits::MultiscalarMul, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodCiphertextCiphertextEqualityProof, zeroize::Zeroize, }; use { @@ -274,11 +275,26 @@ impl CiphertextCiphertextEqualityProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodCiphertextCiphertextEqualityProof { + fn from(decoded_proof: CiphertextCiphertextEqualityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for CiphertextCiphertextEqualityProof { + type Error = EqualityProofVerificationError; + + fn try_from(pod_proof: PodCiphertextCiphertextEqualityProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::str::FromStr, }; diff --git a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs index e951e7c..69f4fc8 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs @@ -20,6 +20,7 @@ use { }, curve25519_dalek::traits::MultiscalarMul, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodCiphertextCommitmentEqualityProof, zeroize::Zeroize, }; use { @@ -250,14 +251,27 @@ impl CiphertextCommitmentEqualityProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodCiphertextCommitmentEqualityProof { + fn from(decoded_proof: CiphertextCommitmentEqualityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for CiphertextCommitmentEqualityProof { + type Error = EqualityProofVerificationError; + + fn try_from(pod_proof: PodCiphertextCommitmentEqualityProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{elgamal::ElGamalSecretKey, pedersen::Pedersen}, - sigma_proofs::pod::PodCiphertextCommitmentEqualityProof, - }, + crate::encryption::{elgamal::ElGamalSecretKey, pedersen::Pedersen}, solana_zk_sdk_pod::encryption::{ elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, pedersen::PodPedersenCommitment, diff --git a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs index e341869..fcc55fa 100644 --- a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_2.rs @@ -20,6 +20,7 @@ use { }, curve25519_dalek::traits::MultiscalarMul, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodGroupedCiphertext2HandlesValidityProof, zeroize::Zeroize, }; use { @@ -243,14 +244,27 @@ impl GroupedCiphertext2HandlesValidityProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodGroupedCiphertext2HandlesValidityProof { + fn from(decoded_proof: GroupedCiphertext2HandlesValidityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for GroupedCiphertext2HandlesValidityProof { + type Error = ValidityProofVerificationError; + + fn try_from(pod_proof: PodGroupedCiphertext2HandlesValidityProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, - sigma_proofs::pod::PodGroupedCiphertext2HandlesValidityProof, - }, + crate::encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, solana_zk_sdk_pod::encryption::{ elgamal::{PodDecryptHandle, PodElGamalPubkey}, pedersen::PodPedersenCommitment, diff --git a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs index 1beab42..c93c302 100644 --- a/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/sigma_proofs/grouped_ciphertext_validity/handles_3.rs @@ -20,6 +20,7 @@ use { }, curve25519_dalek::traits::MultiscalarMul, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodGroupedCiphertext3HandlesValidityProof, zeroize::Zeroize, }; use { @@ -274,14 +275,27 @@ impl GroupedCiphertext3HandlesValidityProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodGroupedCiphertext3HandlesValidityProof { + fn from(decoded_proof: GroupedCiphertext3HandlesValidityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for GroupedCiphertext3HandlesValidityProof { + type Error = ValidityProofVerificationError; + + fn try_from(pod_proof: PodGroupedCiphertext3HandlesValidityProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, - sigma_proofs::pod::PodGroupedCiphertext3HandlesValidityProof, - }, + crate::encryption::{elgamal::ElGamalKeypair, pedersen::Pedersen}, solana_zk_sdk_pod::encryption::{ elgamal::{PodDecryptHandle, PodElGamalCiphertext, PodElGamalPubkey}, pedersen::PodPedersenCommitment, diff --git a/zk-sdk/src/sigma_proofs/mod.rs b/zk-sdk/src/sigma_proofs/mod.rs index c8b847a..2fe0e9e 100644 --- a/zk-sdk/src/sigma_proofs/mod.rs +++ b/zk-sdk/src/sigma_proofs/mod.rs @@ -8,7 +8,6 @@ #![allow(dead_code, unused_imports)] pub mod errors; -pub mod pod; #[cfg(not(target_os = "solana"))] pub mod batched_grouped_ciphertext_validity; @@ -25,32 +24,14 @@ pub mod pubkey_validity; #[cfg(not(target_os = "solana"))] pub mod zero_ciphertext; -/// Byte length of a ciphertext-commitment equality proof -pub const CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN: usize = 192; - -/// Byte length of a ciphertext-ciphertext equality proof -pub const CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN: usize = 224; - -/// Byte length of a grouped ciphertext for 2 handles validity proof -pub const GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN: usize = 160; - -/// Byte length of a grouped ciphertext for 3 handles validity proof -pub const GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = 192; - -/// Byte length of a batched grouped ciphertext for 2 handles validity proof -pub const BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN: usize = 160; - -/// Byte length of a batched grouped ciphertext for 3 handles validity proof -pub const BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = 192; - -/// Byte length of a zero-ciphertext proof -pub const ZERO_CIPHERTEXT_PROOF_LEN: usize = 96; - -/// Byte length of a percentage with cap proof -pub const PERCENTAGE_WITH_CAP_PROOF_LEN: usize = 256; - -/// Byte length of a public key validity proof -pub const PUBKEY_VALIDITY_PROOF_LEN: usize = 64; +pub use solana_zk_sdk_pod::sigma_proofs::{ + BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN, + BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN, + CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN, CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN, + GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN, + GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN, PERCENTAGE_WITH_CAP_PROOF_LEN, + PUBKEY_VALIDITY_PROOF_LEN, ZERO_CIPHERTEXT_PROOF_LEN, +}; #[cfg(not(target_os = "solana"))] use { diff --git a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs index d30be4f..3c47469 100644 --- a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs +++ b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs @@ -26,6 +26,7 @@ use { UNIT_LEN, }, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodPercentageWithCapProof, zeroize::Zeroize, }; use { @@ -608,13 +609,27 @@ fn conditional_select_ristretto( CompressedRistretto(bytes) } +#[cfg(not(target_os = "solana"))] +impl From for PodPercentageWithCapProof { + fn from(decoded_proof: PercentageWithCapProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PercentageWithCapProof { + type Error = PercentageWithCapProofVerificationError; + + fn try_from(pod_proof: PodPercentageWithCapProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { - super::*, - crate::{encryption::pedersen::Pedersen, sigma_proofs::pod::PodPercentageWithCapProof}, - solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, - std::str::FromStr, + super::*, crate::encryption::pedersen::Pedersen, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::str::FromStr, }; #[test] diff --git a/zk-sdk/src/sigma_proofs/pubkey_validity.rs b/zk-sdk/src/sigma_proofs/pubkey_validity.rs index 257c99c..76d940f 100644 --- a/zk-sdk/src/sigma_proofs/pubkey_validity.rs +++ b/zk-sdk/src/sigma_proofs/pubkey_validity.rs @@ -14,6 +14,7 @@ use { UNIT_LEN, }, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodPubkeyValidityProof, zeroize::Zeroize, }; use { @@ -143,12 +144,28 @@ impl PubkeyValidityProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodPubkeyValidityProof { + fn from(decoded_proof: PubkeyValidityProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PubkeyValidityProof { + type Error = PubkeyValidityProofVerificationError; + + fn try_from(pod_proof: PodPubkeyValidityProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { - super::*, crate::sigma_proofs::pod::PodPubkeyValidityProof, bytemuck::Zeroable, - curve25519_dalek::traits::Identity, solana_keypair::Keypair, solana_pubkey::Pubkey, - solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, std::str::FromStr, + super::*, bytemuck::Zeroable, curve25519_dalek::traits::Identity, solana_keypair::Keypair, + solana_pubkey::Pubkey, solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, + std::str::FromStr, }; #[test] diff --git a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs index 4a34136..a45dd1e 100644 --- a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs +++ b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs @@ -15,6 +15,7 @@ use { }, curve25519_dalek::traits::MultiscalarMul, rand::rngs::OsRng, + solana_zk_sdk_pod::sigma_proofs::PodZeroCiphertextProof, zeroize::Zeroize, }; use { @@ -177,16 +178,29 @@ impl ZeroCiphertextProof { } } +#[cfg(not(target_os = "solana"))] +impl From for PodZeroCiphertextProof { + fn from(decoded_proof: ZeroCiphertextProof) -> Self { + Self(decoded_proof.to_bytes()) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for ZeroCiphertextProof { + type Error = ZeroCiphertextProofVerificationError; + + fn try_from(pod_proof: PodZeroCiphertextProof) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + #[cfg(test)] mod test { use { super::*, - crate::{ - encryption::{ - elgamal::{DecryptHandle, ElGamalKeypair}, - pedersen::{Pedersen, PedersenCommitment, PedersenOpening}, - }, - sigma_proofs::pod::PodZeroCiphertextProof, + crate::encryption::{ + elgamal::{DecryptHandle, ElGamalKeypair}, + pedersen::{Pedersen, PedersenCommitment, PedersenOpening}, }, solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::str::FromStr, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index e04af48..fd44f4d 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -5,6 +5,16 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, + sigma_proofs::PodBatchedGroupedCiphertext2HandlesValidityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -18,16 +28,6 @@ use { bytemuck::bytes_of, merlin::Transcript, }; -use { - crate::{ - sigma_proofs::pod::PodBatchedGroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, - }, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedGroupedCiphertextValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs index 557a422..ef26f06 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -5,6 +5,16 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, + sigma_proofs::PodBatchedGroupedCiphertext3HandlesValidityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -18,16 +28,6 @@ use { bytemuck::bytes_of, merlin::Transcript, }; -use { - crate::{ - sigma_proofs::pod::PodBatchedGroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, - }, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs index 90bff04..ead53ac 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs @@ -5,6 +5,14 @@ //! the proof, a prover must provide the decryption key for the first ciphertext and the randomness //! used to generate the second ciphertext. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + sigma_proofs::PodCiphertextCiphertextEqualityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -19,14 +27,6 @@ use { merlin::Transcript, std::convert::TryInto, }; -use { - crate::{ - sigma_proofs::pod::PodCiphertextCiphertextEqualityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs index 524f563..1e7d6c3 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs @@ -5,6 +5,17 @@ //! encrypts/encodes the same message. To generate the proof, a prover must provide the decryption //! key for the first ciphertext and the Pedersen opening for the commitment. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::{ + elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, + sigma_proofs::PodCiphertextCommitmentEqualityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -19,17 +30,6 @@ use { merlin::Transcript, std::convert::TryInto, }; -use { - crate::{ - sigma_proofs::pod::PodCiphertextCommitmentEqualityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::{ - elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction. /// diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs index 3410f13..c83d239 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -5,6 +5,16 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, + sigma_proofs::PodGroupedCiphertext2HandlesValidityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -18,16 +28,6 @@ use { bytemuck::bytes_of, merlin::Transcript, }; -use { - crate::{ - sigma_proofs::pod::PodGroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, - }, -}; /// The instruction data that is needed for the `ProofInstruction::VerifyGroupedCiphertextValidity` /// instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs index d8815c1..f534b58 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -5,6 +5,16 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, + sigma_proofs::PodGroupedCiphertext3HandlesValidityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -18,16 +28,6 @@ use { bytemuck::bytes_of, merlin::Transcript, }; -use { - crate::{ - sigma_proofs::pod::PodGroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, - }, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyGroupedCiphertext3HandlesValidity` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs index 2445bfb..f96fedc 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs @@ -20,11 +20,12 @@ use { use { crate::{ pod::PodU64, - sigma_proofs::pod::PodPercentageWithCapProof, zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, }, bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, + solana_zk_sdk_pod::{ + encryption::pedersen::PodPedersenCommitment, sigma_proofs::PodPercentageWithCapProof, + }, }; /// The instruction data that is needed for the `ProofInstruction::VerifyPercentageWithCap` diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs index 7749705..fd160ba 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs @@ -5,6 +5,13 @@ //! corresponding secret key). To generate the proof, a prover must provide the secret key for the //! public key. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::elgamal::PodElGamalPubkey, sigma_proofs::PodPubkeyValidityProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -16,14 +23,6 @@ use { merlin::Transcript, std::convert::TryInto, }; -use { - crate::{ - sigma_proofs::pod::PodPubkeyValidityProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, -}; /// The instruction data that is needed for the `ProofInstruction::VerifyPubkeyValidity` /// instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs index 0cab726..3a0b7e6 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs @@ -4,6 +4,14 @@ //! certifies that a given ciphertext encrypts the message 0 in the field (`Scalar::zero()`). To //! generate the proof, a prover must provide the decryption key for the ciphertext. +use { + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::{ + encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + sigma_proofs::PodZeroCiphertextProof, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -15,14 +23,6 @@ use { merlin::Transcript, std::convert::TryInto, }; -use { - crate::{ - sigma_proofs::pod::PodZeroCiphertextProof, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, -}; /// The instruction data that is needed for the `ProofInstruction::VerifyZeroCiphertext` instruction. /// From 53994e05b93f9e70e135481e5978441917ccf79b Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Mon, 27 Oct 2025 12:03:37 +0900 Subject: [PATCH 4/7] migrate range proof pod types --- zk-sdk-pod/src/lib.rs | 1 + zk-sdk-pod/src/range_proof.rs | 111 +++++++++++++++ zk-sdk/src/pod.rs | 35 ----- zk-sdk/src/range_proof/mod.rs | 133 ++++++++++++++---- zk-sdk/src/sigma_proofs/mod.rs | 5 +- .../batched_range_proof_u128.rs | 16 +-- .../batched_range_proof_u256.rs | 16 +-- .../batched_range_proof_u64.rs | 16 +-- 8 files changed, 241 insertions(+), 92 deletions(-) create mode 100644 zk-sdk-pod/src/range_proof.rs diff --git a/zk-sdk-pod/src/lib.rs b/zk-sdk-pod/src/lib.rs index 18db44c..443dc1c 100644 --- a/zk-sdk-pod/src/lib.rs +++ b/zk-sdk-pod/src/lib.rs @@ -1,6 +1,7 @@ pub mod encryption; pub mod errors; pub mod macros; +pub mod range_proof; pub mod sigma_proofs; /// Byte length of a compressed Ristretto point or scalar in Curve255519 diff --git a/zk-sdk-pod/src/range_proof.rs b/zk-sdk-pod/src/range_proof.rs new file mode 100644 index 0000000..1fcb364 --- /dev/null +++ b/zk-sdk-pod/src/range_proof.rs @@ -0,0 +1,111 @@ +//! Plain Old Data types for range proofs. + +use { + crate::{ + macros::{impl_from_bytes, impl_from_str}, + RISTRETTO_POINT_LEN, SCALAR_LEN, + }, + base64::{prelude::BASE64_STANDARD, Engine}, + bytemuck::{Pod, Zeroable}, + std::fmt, +}; + +/// Byte length of a range proof excluding the inner-product proof component +pub const RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN: usize = + 5 * RISTRETTO_POINT_LEN + 2 * SCALAR_LEN; + +/// Byte length of an inner-product proof for a vector of length 64 +pub const INNER_PRODUCT_PROOF_U64_LEN: usize = 448; + +/// Byte length of a range proof for an unsigned 64-bit number +pub const RANGE_PROOF_U64_LEN: usize = + INNER_PRODUCT_PROOF_U64_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 672 bytes + +/// Byte length of an inner-product proof for a vector of length 128 +pub const INNER_PRODUCT_PROOF_U128_LEN: usize = 512; + +/// Byte length of a range proof for an unsigned 128-bit number +pub const RANGE_PROOF_U128_LEN: usize = + INNER_PRODUCT_PROOF_U128_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 736 bytes + +/// Byte length of an inner-product proof for a vector of length 256 +pub const INNER_PRODUCT_PROOF_U256_LEN: usize = 576; + +/// Byte length of a range proof for an unsigned 256-bit number +pub const RANGE_PROOF_U256_LEN: usize = + INNER_PRODUCT_PROOF_U256_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 800 bytes + +/// The `RangeProof` type as a `Pod` restricted to proofs on 64-bit numbers. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct PodRangeProofU64(pub [u8; RANGE_PROOF_U64_LEN]); + +const RANGE_PROOF_U64_MAX_BASE64_LEN: usize = 896; + +impl fmt::Display for PodRangeProofU64 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodRangeProofU64, + BYTES_LEN = RANGE_PROOF_U64_LEN, + BASE64_LEN = RANGE_PROOF_U64_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodRangeProofU64, BYTES_LEN = RANGE_PROOF_U64_LEN); + +/// The `RangeProof` type as a `Pod` restricted to proofs on 128-bit numbers. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct PodRangeProofU128(pub [u8; RANGE_PROOF_U128_LEN]); + +const RANGE_PROOF_U128_MAX_BASE64_LEN: usize = 984; + +impl fmt::Display for PodRangeProofU128 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodRangeProofU128, + BYTES_LEN = RANGE_PROOF_U128_LEN, + BASE64_LEN = RANGE_PROOF_U128_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodRangeProofU128, BYTES_LEN = RANGE_PROOF_U128_LEN); + +/// The `RangeProof` type as a `Pod` restricted to proofs on 256-bit numbers. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct PodRangeProofU256(pub [u8; RANGE_PROOF_U256_LEN]); + +const RANGE_PROOF_U256_MAX_BASE64_LEN: usize = 1068; + +impl fmt::Display for PodRangeProofU256 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", BASE64_STANDARD.encode(self.0)) + } +} + +impl_from_str!( + TYPE = PodRangeProofU256, + BYTES_LEN = RANGE_PROOF_U256_LEN, + BASE64_LEN = RANGE_PROOF_U256_MAX_BASE64_LEN +); + +impl_from_bytes!(TYPE = PodRangeProofU256, BYTES_LEN = RANGE_PROOF_U256_LEN); + +// The range proof pod types are wrappers for byte arrays, which are both `Pod` and `Zeroable`. However, +// the marker traits `bytemuck::Pod` and `bytemuck::Zeroable` can only be derived for power-of-two +// length byte arrays. Directly implement these traits for the range proof pod types. +unsafe impl Zeroable for PodRangeProofU64 {} +unsafe impl Pod for PodRangeProofU64 {} + +unsafe impl Zeroable for PodRangeProofU128 {} +unsafe impl Pod for PodRangeProofU128 {} + +unsafe impl Zeroable for PodRangeProofU256 {} +unsafe impl Pod for PodRangeProofU256 {} diff --git a/zk-sdk/src/pod.rs b/zk-sdk/src/pod.rs index d939e47..2240b5c 100644 --- a/zk-sdk/src/pod.rs +++ b/zk-sdk/src/pod.rs @@ -27,38 +27,3 @@ impl From for u64 { Self::from_le_bytes(pod.0) } } - -macro_rules! impl_from_str { - (TYPE = $type:ident, BYTES_LEN = $bytes_len:expr, BASE64_LEN = $base64_len:expr) => { - impl std::str::FromStr for $type { - type Err = crate::errors::ParseError; - - fn from_str(s: &str) -> Result { - if s.len() > $base64_len { - return Err(Self::Err::WrongSize); - } - let mut bytes = [0u8; $bytes_len]; - let decoded_len = BASE64_STANDARD - .decode_slice(s, &mut bytes) - .map_err(|_| Self::Err::Invalid)?; - if decoded_len != $bytes_len { - Err(Self::Err::WrongSize) - } else { - Ok($type(bytes)) - } - } - } - }; -} -pub(crate) use impl_from_str; - -macro_rules! impl_from_bytes { - (TYPE = $type:ident, BYTES_LEN = $bytes_len:expr) => { - impl std::convert::From<[u8; $bytes_len]> for $type { - fn from(bytes: [u8; $bytes_len]) -> Self { - Self(bytes) - } - } - }; -} -pub(crate) use impl_from_bytes; diff --git a/zk-sdk/src/range_proof/mod.rs b/zk-sdk/src/range_proof/mod.rs index 8822adc..745a804 100644 --- a/zk-sdk/src/range_proof/mod.rs +++ b/zk-sdk/src/range_proof/mod.rs @@ -14,7 +14,6 @@ #![allow(dead_code)] -use crate::{RISTRETTO_POINT_LEN, SCALAR_LEN}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -25,6 +24,7 @@ use { inner_product::InnerProductProof, }, transcript::TranscriptProtocol, + UNIT_LEN, }, core::iter, curve25519_dalek::traits::MultiscalarMul, @@ -35,13 +35,12 @@ use { }, merlin::Transcript, rand::rngs::OsRng, + solana_zk_sdk_pod::range_proof::{PodRangeProofU128, PodRangeProofU256, PodRangeProofU64}, subtle::{Choice, ConditionallySelectable}, zeroize::Zeroize, }; pub mod errors; -pub mod pod; - #[cfg(not(target_os = "solana"))] pub mod generators; #[cfg(not(target_os = "solana"))] @@ -49,30 +48,11 @@ pub mod inner_product; #[cfg(not(target_os = "solana"))] pub mod util; -/// Byte length of a range proof excluding the inner-product proof component -pub const RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN: usize = - 5 * RISTRETTO_POINT_LEN + 2 * SCALAR_LEN; - -/// Byte length of an inner-product proof for a vector of length 64 -pub const INNER_PRODUCT_PROOF_U64_LEN: usize = 448; - -/// Byte length of a range proof for an unsigned 64-bit number -pub const RANGE_PROOF_U64_LEN: usize = - INNER_PRODUCT_PROOF_U64_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 672 bytes - -/// Byte length of an inner-product proof for a vector of length 128 -pub const INNER_PRODUCT_PROOF_U128_LEN: usize = 512; - -/// Byte length of a range proof for an unsigned 128-bit number -pub const RANGE_PROOF_U128_LEN: usize = - INNER_PRODUCT_PROOF_U128_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 736 bytes - -/// Byte length of an inner-product proof for a vector of length 256 -pub const INNER_PRODUCT_PROOF_U256_LEN: usize = 576; - -/// Byte length of a range proof for an unsigned 256-bit number -pub const RANGE_PROOF_U256_LEN: usize = - INNER_PRODUCT_PROOF_U256_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN; // 800 bytes +pub use solana_zk_sdk_pod::range_proof::{ + INNER_PRODUCT_PROOF_U128_LEN, INNER_PRODUCT_PROOF_U256_LEN, INNER_PRODUCT_PROOF_U64_LEN, + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN, RANGE_PROOF_U128_LEN, RANGE_PROOF_U256_LEN, + RANGE_PROOF_U64_LEN, +}; /// A Bulletproofs range proof. #[allow(non_snake_case)] @@ -491,6 +471,102 @@ impl RangeProof { } } +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof { + type Error = RangeProofVerificationError; + + fn try_from(pod_proof: PodRangeProofU64) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PodRangeProofU64 { + type Error = RangeProofVerificationError; + + fn try_from(decoded_proof: RangeProof) -> Result { + if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U64_LEN { + return Err(RangeProofVerificationError::Deserialization); + } + + let mut buf = [0_u8; RANGE_PROOF_U64_LEN]; + copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); + buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U64_LEN] + .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); + Ok(PodRangeProofU64(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof { + type Error = RangeProofVerificationError; + + fn try_from(pod_proof: PodRangeProofU128) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PodRangeProofU128 { + type Error = RangeProofVerificationError; + + fn try_from(decoded_proof: RangeProof) -> Result { + if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U128_LEN { + return Err(RangeProofVerificationError::Deserialization); + } + + let mut buf = [0_u8; RANGE_PROOF_U128_LEN]; + copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); + buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U128_LEN] + .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); + Ok(PodRangeProofU128(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for RangeProof { + type Error = RangeProofVerificationError; + + fn try_from(pod_proof: PodRangeProofU256) -> Result { + Self::from_bytes(&pod_proof.0) + } +} + +#[cfg(not(target_os = "solana"))] +impl TryFrom for PodRangeProofU256 { + type Error = RangeProofVerificationError; + + fn try_from(decoded_proof: RangeProof) -> Result { + if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U256_LEN { + return Err(RangeProofVerificationError::Deserialization); + } + + let mut buf = [0_u8; RANGE_PROOF_U256_LEN]; + copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); + buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U256_LEN] + .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); + Ok(PodRangeProofU256(buf)) + } +} + +#[cfg(not(target_os = "solana"))] +fn copy_range_proof_modulo_inner_product_proof(proof: &RangeProof, buf: &mut [u8]) { + let mut chunks = buf.chunks_mut(UNIT_LEN); + chunks.next().unwrap().copy_from_slice(proof.A.as_bytes()); + chunks.next().unwrap().copy_from_slice(proof.S.as_bytes()); + chunks.next().unwrap().copy_from_slice(proof.T_1.as_bytes()); + chunks.next().unwrap().copy_from_slice(proof.T_2.as_bytes()); + chunks.next().unwrap().copy_from_slice(proof.t_x.as_bytes()); + chunks + .next() + .unwrap() + .copy_from_slice(proof.t_x_blinding.as_bytes()); + chunks + .next() + .unwrap() + .copy_from_slice(proof.e_blinding.as_bytes()); +} + /// Computes the `delta(y,z)` term for the verification equation. /// /// This term is a function of the challenges `y` and `z` and the proof dimensions. @@ -514,8 +590,7 @@ fn delta(bit_lengths: &[usize], y: &Scalar, z: &Scalar) -> Scalar { #[cfg(test)] mod tests { use { - super::*, crate::range_proof::pod::PodRangeProofU128, - solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::str::FromStr, + super::*, solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::str::FromStr, }; #[test] diff --git a/zk-sdk/src/sigma_proofs/mod.rs b/zk-sdk/src/sigma_proofs/mod.rs index 2fe0e9e..3d3eddc 100644 --- a/zk-sdk/src/sigma_proofs/mod.rs +++ b/zk-sdk/src/sigma_proofs/mod.rs @@ -35,7 +35,10 @@ pub use solana_zk_sdk_pod::sigma_proofs::{ #[cfg(not(target_os = "solana"))] use { - crate::{sigma_proofs::errors::SigmaProofVerificationError, RISTRETTO_POINT_LEN, SCALAR_LEN}, + crate::{ + sigma_proofs::errors::SigmaProofVerificationError, RISTRETTO_POINT_LEN, SCALAR_LEN, + UNIT_LEN, + }, curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar}, }; diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs index df292c1..2385f63 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs @@ -1,5 +1,12 @@ //! The 128-bit batched range proof instruction. +use { + crate::zk_elgamal_proof_program::proof_data::{ + batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::range_proof::PodRangeProofU128, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -12,15 +19,6 @@ use { }, std::convert::TryInto, }; -use { - crate::{ - range_proof::pod::PodRangeProofU128, - zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, - }, - }, - bytemuck_derive::{Pod, Zeroable}, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedRangeProofU128` instruction. diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs index 42ace83..e5e73e8 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs @@ -1,5 +1,12 @@ //! The 256-bit batched range proof instruction. +use { + crate::zk_elgamal_proof_program::proof_data::{ + batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::range_proof::PodRangeProofU256, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -12,15 +19,6 @@ use { }, std::convert::TryInto, }; -use { - crate::{ - range_proof::pod::PodRangeProofU256, - zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, - }, - }, - bytemuck_derive::{Pod, Zeroable}, -}; #[cfg(not(target_os = "solana"))] const BATCHED_RANGE_PROOF_U256_BIT_LENGTH: usize = 256; diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs index 3104fcc..fa239b5 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs @@ -1,5 +1,12 @@ //! The 64-bit batched range proof instruction. +use { + crate::zk_elgamal_proof_program::proof_data::{ + batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + }, + bytemuck_derive::{Pod, Zeroable}, + solana_zk_sdk_pod::range_proof::PodRangeProofU64, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -12,15 +19,6 @@ use { }, std::convert::TryInto, }; -use { - crate::{ - range_proof::pod::PodRangeProofU64, - zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, - }, - }, - bytemuck_derive::{Pod, Zeroable}, -}; /// The instruction data that is needed for the /// `ProofInstruction::VerifyBatchedRangeProofU64` instruction. From 03a05215e5b2d99716c4d009371823b9ff49e0df Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 28 Oct 2025 11:09:39 +0900 Subject: [PATCH 5/7] migrate proof data types --- Cargo.lock | 1 + zk-sdk-pod/src/lib.rs | 2 + zk-sdk-pod/src/num.rs | 29 ++++++++ .../handles_2.rs | 34 +++++++++ .../handles_3.rs | 36 +++++++++ .../mod.rs | 13 ++++ .../batched_range_proof_u128.rs | 21 ++++++ .../batched_range_proof_u256.rs | 21 ++++++ .../batched_range_proof_u64.rs | 21 ++++++ .../src/proof_data/batched_range_proof/mod.rs | 29 ++++++++ .../ciphertext_ciphertext_equality.rs | 33 +++++++++ .../ciphertext_commitment_equality.rs | 36 +++++++++ .../grouped_ciphertext_validity/handles_2.rs | 32 ++++++++ .../grouped_ciphertext_validity/handles_3.rs | 34 +++++++++ .../grouped_ciphertext_validity/mod.rs | 11 +++ zk-sdk-pod/src/proof_data/mod.rs | 8 ++ .../src/proof_data/percentage_with_cap.rs | 42 +++++++++++ zk-sdk-pod/src/proof_data/pubkey_validity.rs | 27 +++++++ zk-sdk-pod/src/proof_data/zero_ciphertext.rs | 32 ++++++++ zk-sdk-wasm-js/Cargo.toml | 1 + .../handles_2.rs | 3 +- .../handles_3.rs | 3 +- .../ciphertext_ciphertext_equality.rs | 3 +- .../ciphertext_commitment_equality.rs | 3 +- .../grouped_ciphertext_validity/handles_2.rs | 3 +- .../grouped_ciphertext_validity/handles_3.rs | 3 +- zk-sdk-wasm-js/src/proof_data/mod.rs | 58 +++++++-------- .../src/proof_data/percentage_with_cap.rs | 5 +- .../src/proof_data/pubkey_validity.rs | 5 +- .../src/proof_data/zero_ciphertext.rs | 5 +- zk-sdk/src/lib.rs | 1 - .../handles_2.rs | 54 ++++++-------- .../handles_3.rs | 58 +++++++-------- .../mod.rs | 10 +-- .../batched_range_proof_u128.rs | 41 +++++------ .../batched_range_proof_u256.rs | 42 +++++------ .../batched_range_proof_u64.rs | 40 +++++----- .../proof_data/batched_range_proof/mod.rs | 57 ++++++++------- .../ciphertext_ciphertext_equality.rs | 48 +++++------- .../ciphertext_commitment_equality.rs | 46 +++++------- .../grouped_ciphertext_validity/handles_2.rs | 47 +++++------- .../grouped_ciphertext_validity/handles_3.rs | 50 +++++-------- .../grouped_ciphertext_validity/mod.rs | 8 +- .../proof_data/mod.rs | 64 +++++++++++----- .../proof_data/percentage_with_cap.rs | 73 +++++++------------ .../proof_data/pubkey_validity.rs | 37 +++------- .../proof_data/zero_ciphertext.rs | 45 ++++-------- 47 files changed, 828 insertions(+), 447 deletions(-) create mode 100644 zk-sdk-pod/src/num.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/mod.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u128.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u256.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u64.rs create mode 100644 zk-sdk-pod/src/proof_data/batched_range_proof/mod.rs create mode 100644 zk-sdk-pod/src/proof_data/ciphertext_ciphertext_equality.rs create mode 100644 zk-sdk-pod/src/proof_data/ciphertext_commitment_equality.rs create mode 100644 zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_2.rs create mode 100644 zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_3.rs create mode 100644 zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/mod.rs create mode 100644 zk-sdk-pod/src/proof_data/mod.rs create mode 100644 zk-sdk-pod/src/proof_data/percentage_with_cap.rs create mode 100644 zk-sdk-pod/src/proof_data/pubkey_validity.rs create mode 100644 zk-sdk-pod/src/proof_data/zero_ciphertext.rs diff --git a/Cargo.lock b/Cargo.lock index ada04f9..e77d91a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -976,6 +976,7 @@ dependencies = [ "getrandom", "js-sys", "solana-zk-sdk", + "solana-zk-sdk-pod", "wasm-bindgen", "wasm-bindgen-test", ] diff --git a/zk-sdk-pod/src/lib.rs b/zk-sdk-pod/src/lib.rs index 443dc1c..27cb817 100644 --- a/zk-sdk-pod/src/lib.rs +++ b/zk-sdk-pod/src/lib.rs @@ -1,6 +1,8 @@ pub mod encryption; pub mod errors; pub mod macros; +pub mod num; +pub mod proof_data; pub mod range_proof; pub mod sigma_proofs; diff --git a/zk-sdk-pod/src/num.rs b/zk-sdk-pod/src/num.rs new file mode 100644 index 0000000..2240b5c --- /dev/null +++ b/zk-sdk-pod/src/num.rs @@ -0,0 +1,29 @@ +use bytemuck_derive::{Pod, Zeroable}; + +#[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) + } +} diff --git a/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs new file mode 100644 index 0000000..21d7365 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -0,0 +1,34 @@ +use { + crate::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, + sigma_proofs::PodBatchedGroupedCiphertext2HandlesValidityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyBatchedGroupedCiphertextValidity` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedGroupedCiphertext2HandlesValidityProofData { + pub context: BatchedGroupedCiphertext2HandlesValidityProofContext, + + pub proof: PodBatchedGroupedCiphertext2HandlesValidityProof, +} + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedGroupedCiphertext2HandlesValidityProofContext { + pub first_pubkey: PodElGamalPubkey, // 32 bytes + + pub second_pubkey: PodElGamalPubkey, // 32 bytes + + pub grouped_ciphertext_lo: PodGroupedElGamalCiphertext2Handles, // 96 bytes + + pub grouped_ciphertext_hi: PodGroupedElGamalCiphertext2Handles, // 96 bytes +} diff --git a/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs new file mode 100644 index 0000000..be8e7ca --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -0,0 +1,36 @@ +use { + crate::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, + sigma_proofs::PodBatchedGroupedCiphertext3HandlesValidityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedGroupedCiphertext3HandlesValidityProofData { + pub context: BatchedGroupedCiphertext3HandlesValidityProofContext, + + pub proof: PodBatchedGroupedCiphertext3HandlesValidityProof, +} + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedGroupedCiphertext3HandlesValidityProofContext { + pub first_pubkey: PodElGamalPubkey, // 32 bytes + + pub second_pubkey: PodElGamalPubkey, // 32 bytes + + pub third_pubkey: PodElGamalPubkey, // 32 bytes + + pub grouped_ciphertext_lo: PodGroupedElGamalCiphertext3Handles, // 128 bytes + + pub grouped_ciphertext_hi: PodGroupedElGamalCiphertext3Handles, // 128 bytes +} diff --git a/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/mod.rs b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/mod.rs new file mode 100644 index 0000000..70d2a7e --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_grouped_ciphertext_validity/mod.rs @@ -0,0 +1,13 @@ +mod handles_2; +mod handles_3; + +pub use { + handles_2::{ + BatchedGroupedCiphertext2HandlesValidityProofContext, + BatchedGroupedCiphertext2HandlesValidityProofData, + }, + handles_3::{ + BatchedGroupedCiphertext3HandlesValidityProofContext, + BatchedGroupedCiphertext3HandlesValidityProofData, + }, +}; diff --git a/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u128.rs b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u128.rs new file mode 100644 index 0000000..c307949 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u128.rs @@ -0,0 +1,21 @@ +use { + crate::{ + proof_data::batched_range_proof::BatchedRangeProofContext, range_proof::PodRangeProofU128, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyBatchedRangeProofU128` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedRangeProofU128Data { + /// The context data for a batched range proof + pub context: BatchedRangeProofContext, + + /// The batched range proof + pub proof: PodRangeProofU128, +} diff --git a/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u256.rs b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u256.rs new file mode 100644 index 0000000..1a0063e --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u256.rs @@ -0,0 +1,21 @@ +use { + crate::{ + proof_data::batched_range_proof::BatchedRangeProofContext, range_proof::PodRangeProofU256, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::BatchedRangeProofU256Data` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedRangeProofU256Data { + /// The context data for a batched range proof + pub context: BatchedRangeProofContext, + + /// The batched range proof + pub proof: PodRangeProofU256, +} diff --git a/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u64.rs b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u64.rs new file mode 100644 index 0000000..46aed4b --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_range_proof/batched_range_proof_u64.rs @@ -0,0 +1,21 @@ +use { + crate::{ + proof_data::batched_range_proof::BatchedRangeProofContext, range_proof::PodRangeProofU64, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyBatchedRangeProofU64` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedRangeProofU64Data { + /// The context data for a batched range proof + pub context: BatchedRangeProofContext, + + /// The batched range proof + pub proof: PodRangeProofU64, +} diff --git a/zk-sdk-pod/src/proof_data/batched_range_proof/mod.rs b/zk-sdk-pod/src/proof_data/batched_range_proof/mod.rs new file mode 100644 index 0000000..ee6bfda --- /dev/null +++ b/zk-sdk-pod/src/proof_data/batched_range_proof/mod.rs @@ -0,0 +1,29 @@ +use { + crate::encryption::pedersen::PodPedersenCommitment, + bytemuck_derive::{Pod, Zeroable}, +}; + +pub mod batched_range_proof_u128; +pub mod batched_range_proof_u256; +pub mod batched_range_proof_u64; + +pub use { + batched_range_proof_u128::BatchedRangeProofU128Data, + batched_range_proof_u256::BatchedRangeProofU256Data, + batched_range_proof_u64::BatchedRangeProofU64Data, +}; + +/// The maximum number of Pedersen commitments that can be processed in a single batched range proof. +const MAX_COMMITMENTS: usize = 8; + +/// The context data needed to verify a range-proof for a Pedersen committed value. +/// +/// This struct holds the public information that a batched range proof certifies. It includes the +/// Pedersen commitments and their corresponding bit lengths. This context is shared by all +/// `VerifyBatchedRangeProof{N}` instructions. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct BatchedRangeProofContext { + pub commitments: [PodPedersenCommitment; MAX_COMMITMENTS], + pub bit_lengths: [u8; MAX_COMMITMENTS], +} diff --git a/zk-sdk-pod/src/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk-pod/src/proof_data/ciphertext_ciphertext_equality.rs new file mode 100644 index 0000000..7bac7a8 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/ciphertext_ciphertext_equality.rs @@ -0,0 +1,33 @@ +use { + crate::{ + encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + sigma_proofs::PodCiphertextCiphertextEqualityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct CiphertextCiphertextEqualityProofData { + pub context: CiphertextCiphertextEqualityProofContext, + + pub proof: PodCiphertextCiphertextEqualityProof, +} + +/// The context data needed to verify a ciphertext-ciphertext equality proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct CiphertextCiphertextEqualityProofContext { + pub first_pubkey: PodElGamalPubkey, // 32 bytes + + pub second_pubkey: PodElGamalPubkey, // 32 bytes + + pub first_ciphertext: PodElGamalCiphertext, // 64 bytes + + pub second_ciphertext: PodElGamalCiphertext, // 64 bytes +} diff --git a/zk-sdk-pod/src/proof_data/ciphertext_commitment_equality.rs b/zk-sdk-pod/src/proof_data/ciphertext_commitment_equality.rs new file mode 100644 index 0000000..7836a70 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/ciphertext_commitment_equality.rs @@ -0,0 +1,36 @@ +use { + crate::{ + encryption::{ + elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, + sigma_proofs::PodCiphertextCommitmentEqualityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct CiphertextCommitmentEqualityProofData { + pub context: CiphertextCommitmentEqualityProofContext, + pub proof: PodCiphertextCommitmentEqualityProof, +} + +/// The context data needed to verify a ciphertext-commitment equality proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct CiphertextCommitmentEqualityProofContext { + /// The ElGamal pubkey + pub pubkey: PodElGamalPubkey, // 32 bytes + + /// The ciphertext encrypted under the ElGamal pubkey + pub ciphertext: PodElGamalCiphertext, // 64 bytes + + /// The Pedersen commitment + pub commitment: PodPedersenCommitment, // 32 bytes +} diff --git a/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_2.rs new file mode 100644 index 0000000..2197510 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -0,0 +1,32 @@ +use { + crate::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + }, + sigma_proofs::PodGroupedCiphertext2HandlesValidityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the `ProofInstruction::VerifyGroupedCiphertextValidity` +/// instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct GroupedCiphertext2HandlesValidityProofData { + pub context: GroupedCiphertext2HandlesValidityProofContext, + + pub proof: PodGroupedCiphertext2HandlesValidityProof, +} + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct GroupedCiphertext2HandlesValidityProofContext { + pub first_pubkey: PodElGamalPubkey, // 32 bytes + + pub second_pubkey: PodElGamalPubkey, // 32 bytes + + pub grouped_ciphertext: PodGroupedElGamalCiphertext2Handles, // 96 bytes +} diff --git a/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_3.rs new file mode 100644 index 0000000..86259d4 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -0,0 +1,34 @@ +use { + crate::{ + encryption::{ + elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + }, + sigma_proofs::PodGroupedCiphertext3HandlesValidityProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the +/// `ProofInstruction::VerifyGroupedCiphertext3HandlesValidity` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct GroupedCiphertext3HandlesValidityProofData { + pub context: GroupedCiphertext3HandlesValidityProofContext, + + pub proof: PodGroupedCiphertext3HandlesValidityProof, +} + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct GroupedCiphertext3HandlesValidityProofContext { + pub first_pubkey: PodElGamalPubkey, // 32 bytes + + pub second_pubkey: PodElGamalPubkey, // 32 bytes + + pub third_pubkey: PodElGamalPubkey, // 32 bytes + + pub grouped_ciphertext: PodGroupedElGamalCiphertext3Handles, // 128 bytes +} diff --git a/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/mod.rs b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/mod.rs new file mode 100644 index 0000000..7f1149b --- /dev/null +++ b/zk-sdk-pod/src/proof_data/grouped_ciphertext_validity/mod.rs @@ -0,0 +1,11 @@ +mod handles_2; +mod handles_3; + +pub use { + handles_2::{ + GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, + }, + handles_3::{ + GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, + }, +}; diff --git a/zk-sdk-pod/src/proof_data/mod.rs b/zk-sdk-pod/src/proof_data/mod.rs new file mode 100644 index 0000000..396badc --- /dev/null +++ b/zk-sdk-pod/src/proof_data/mod.rs @@ -0,0 +1,8 @@ +pub mod batched_grouped_ciphertext_validity; +pub mod batched_range_proof; +pub mod ciphertext_ciphertext_equality; +pub mod ciphertext_commitment_equality; +pub mod grouped_ciphertext_validity; +pub mod percentage_with_cap; +pub mod pubkey_validity; +pub mod zero_ciphertext; diff --git a/zk-sdk-pod/src/proof_data/percentage_with_cap.rs b/zk-sdk-pod/src/proof_data/percentage_with_cap.rs new file mode 100644 index 0000000..f43d164 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/percentage_with_cap.rs @@ -0,0 +1,42 @@ +use { + crate::{ + encryption::pedersen::PodPedersenCommitment, num::PodU64, + sigma_proofs::PodPercentageWithCapProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the `ProofInstruction::VerifyPercentageWithCap` +/// instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct PercentageWithCapProofData { + pub context: PercentageWithCapProofContext, + + pub proof: PodPercentageWithCapProof, +} + +/// The context data needed to verify a percentage-with-cap proof. +/// +/// We refer to [`ZK ElGamal proof`] for the formal details on how the percentage-with-cap proof is +/// computed. +/// +/// [`ZK ElGamal proof`]: https://docs.solanalabs.com/runtime/zk-token-proof +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct PercentageWithCapProofContext { + /// The Pedersen commitment to the percentage amount. + pub percentage_commitment: PodPedersenCommitment, + + /// The Pedersen commitment to the delta amount. + pub delta_commitment: PodPedersenCommitment, + + /// The Pedersen commitment to the claimed amount. + pub claimed_commitment: PodPedersenCommitment, + + /// The maximum cap bound. + pub max_value: PodU64, +} diff --git a/zk-sdk-pod/src/proof_data/pubkey_validity.rs b/zk-sdk-pod/src/proof_data/pubkey_validity.rs new file mode 100644 index 0000000..eb34335 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/pubkey_validity.rs @@ -0,0 +1,27 @@ +use { + crate::{encryption::elgamal::PodElGamalPubkey, sigma_proofs::PodPubkeyValidityProof}, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the `ProofInstruction::VerifyPubkeyValidity` +/// instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct PubkeyValidityProofData { + /// The context data for the public key validity proof + pub context: PubkeyValidityProofContext, // 32 bytes + + /// Proof that the public key is well-formed + pub proof: PodPubkeyValidityProof, // 64 bytes +} + +/// The context data needed to verify a pubkey validity proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct PubkeyValidityProofContext { + /// The public key to be proved + pub pubkey: PodElGamalPubkey, // 32 bytes +} diff --git a/zk-sdk-pod/src/proof_data/zero_ciphertext.rs b/zk-sdk-pod/src/proof_data/zero_ciphertext.rs new file mode 100644 index 0000000..aed0f78 --- /dev/null +++ b/zk-sdk-pod/src/proof_data/zero_ciphertext.rs @@ -0,0 +1,32 @@ +use { + crate::{ + encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + sigma_proofs::PodZeroCiphertextProof, + }, + bytemuck_derive::{Pod, Zeroable}, +}; + +/// The instruction data that is needed for the `ProofInstruction::VerifyZeroCiphertext` instruction. +/// +/// It includes the cryptographic proof as well as the context data information needed to verify +/// the proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct ZeroCiphertextProofData { + /// The context data for the zero-ciphertext proof + pub context: ZeroCiphertextProofContext, // 96 bytes + + /// Proof that the ciphertext is zero + pub proof: PodZeroCiphertextProof, // 96 bytes +} + +/// The context data needed to verify a zero-ciphertext proof. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct ZeroCiphertextProofContext { + /// The ElGamal pubkey associated with the ElGamal ciphertext + pub pubkey: PodElGamalPubkey, // 32 bytes + + /// The ElGamal ciphertext that encrypts zero + pub ciphertext: PodElGamalCiphertext, // 64 bytes +} diff --git a/zk-sdk-wasm-js/Cargo.toml b/zk-sdk-wasm-js/Cargo.toml index cad7eeb..219a3cf 100644 --- a/zk-sdk-wasm-js/Cargo.toml +++ b/zk-sdk-wasm-js/Cargo.toml @@ -21,6 +21,7 @@ test-browser = [] [dependencies] solana-zk-sdk = { workspace = true } +solana-zk-sdk-pod = { workspace = true } bytemuck = { workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index 966fda2..4c0b692 100644 --- a/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - batched_grouped_ciphertext_validity, ZkProofData, + BatchedGroupedCiphertext2HandlesValidityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::batched_grouped_ciphertext_validity, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs index ac14960..5b76486 100644 --- a/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk-wasm-js/src/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - batched_grouped_ciphertext_validity, ZkProofData, + BatchedGroupedCiphertext3HandlesValidityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::batched_grouped_ciphertext_validity, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk-wasm-js/src/proof_data/ciphertext_ciphertext_equality.rs index 75d064b..9d818c0 100644 --- a/zk-sdk-wasm-js/src/proof_data/ciphertext_ciphertext_equality.rs +++ b/zk-sdk-wasm-js/src/proof_data/ciphertext_ciphertext_equality.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - ciphertext_ciphertext_equality, ZkProofData, + CiphertextCiphertextEqualityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::ciphertext_ciphertext_equality, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/ciphertext_commitment_equality.rs b/zk-sdk-wasm-js/src/proof_data/ciphertext_commitment_equality.rs index 03d9782..385f8fe 100644 --- a/zk-sdk-wasm-js/src/proof_data/ciphertext_commitment_equality.rs +++ b/zk-sdk-wasm-js/src/proof_data/ciphertext_commitment_equality.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - ciphertext_commitment_equality, ZkProofData, + CiphertextCommitmentEqualityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::ciphertext_commitment_equality, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_2.rs index af344aa..cf5462d 100644 --- a/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - grouped_ciphertext_validity, ZkProofData, + GroupedCiphertext2HandlesValidityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::grouped_ciphertext_validity, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_3.rs index 8fb0fc7..df7563b 100644 --- a/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk-wasm-js/src/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -5,8 +5,9 @@ use { }, js_sys::Uint8Array, solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ - grouped_ciphertext_validity, ZkProofData, + GroupedCiphertext3HandlesValidityProofDataExt, ZkProofData, }, + solana_zk_sdk_pod::proof_data::grouped_ciphertext_validity, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/mod.rs b/zk-sdk-wasm-js/src/proof_data/mod.rs index acbfe65..c974db2 100644 --- a/zk-sdk-wasm-js/src/proof_data/mod.rs +++ b/zk-sdk-wasm-js/src/proof_data/mod.rs @@ -1,35 +1,35 @@ -pub mod batched_grouped_ciphertext_validity; -pub mod batched_range_proof; +// pub mod batched_grouped_ciphertext_validity; +// pub mod batched_range_proof; pub mod ciphertext_ciphertext_equality; pub mod ciphertext_commitment_equality; pub mod grouped_ciphertext_validity; pub mod percentage_with_cap; pub mod pubkey_validity; -pub mod zero_ciphertext; +// pub mod zero_ciphertext; -pub use { - batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext2HandlesValidityProofContext, - BatchedGroupedCiphertext2HandlesValidityProofData, - BatchedGroupedCiphertext3HandlesValidityProofContext, - BatchedGroupedCiphertext3HandlesValidityProofData, - }, - batched_range_proof::{ - batched_range_proof_u128::BatchedRangeProofU128Data, - batched_range_proof_u256::BatchedRangeProofU256Data, - batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, - }, - ciphertext_ciphertext_equality::{ - CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, - }, - ciphertext_commitment_equality::{ - CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, - }, - grouped_ciphertext_validity::{ - GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, - GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, - }, - percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, - pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, - zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, -}; +// pub use { +// batched_grouped_ciphertext_validity::{ +// BatchedGroupedCiphertext2HandlesValidityProofContext, +// BatchedGroupedCiphertext2HandlesValidityProofData, +// BatchedGroupedCiphertext3HandlesValidityProofContext, +// BatchedGroupedCiphertext3HandlesValidityProofData, +// }, +// batched_range_proof::{ +// batched_range_proof_u128::BatchedRangeProofU128Data, +// batched_range_proof_u256::BatchedRangeProofU256Data, +// batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, +// }, +// ciphertext_ciphertext_equality::{ +// CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, +// }, +// ciphertext_commitment_equality::{ +// CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, +// }, +// grouped_ciphertext_validity::{ +// GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, +// GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, +// }, +// percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, +// pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, +// zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, +// }; diff --git a/zk-sdk-wasm-js/src/proof_data/percentage_with_cap.rs b/zk-sdk-wasm-js/src/proof_data/percentage_with_cap.rs index 1127f8a..629e249 100644 --- a/zk-sdk-wasm-js/src/proof_data/percentage_with_cap.rs +++ b/zk-sdk-wasm-js/src/proof_data/percentage_with_cap.rs @@ -1,7 +1,10 @@ use { crate::encryption::pedersen::{PedersenCommitment, PedersenOpening}, js_sys::Uint8Array, - solana_zk_sdk::zk_elgamal_proof_program::proof_data::{percentage_with_cap, ZkProofData}, + solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ + PercentageWithCapProofDataExt, ZkProofData, + }, + solana_zk_sdk_pod::proof_data::percentage_with_cap, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/pubkey_validity.rs b/zk-sdk-wasm-js/src/proof_data/pubkey_validity.rs index bfa6ba7..e5e6819 100644 --- a/zk-sdk-wasm-js/src/proof_data/pubkey_validity.rs +++ b/zk-sdk-wasm-js/src/proof_data/pubkey_validity.rs @@ -1,7 +1,10 @@ use { crate::encryption::elgamal::ElGamalKeypair, js_sys::Uint8Array, - solana_zk_sdk::zk_elgamal_proof_program::proof_data::{pubkey_validity, ZkProofData}, + solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ + PubkeyValidityProofDataExt, ZkProofData, + }, + solana_zk_sdk_pod::proof_data::pubkey_validity, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk-wasm-js/src/proof_data/zero_ciphertext.rs b/zk-sdk-wasm-js/src/proof_data/zero_ciphertext.rs index 1556c34..9a1fc0e 100644 --- a/zk-sdk-wasm-js/src/proof_data/zero_ciphertext.rs +++ b/zk-sdk-wasm-js/src/proof_data/zero_ciphertext.rs @@ -1,7 +1,10 @@ use { crate::encryption::elgamal::{ElGamalCiphertext, ElGamalKeypair}, js_sys::Uint8Array, - solana_zk_sdk::zk_elgamal_proof_program::proof_data::{zero_ciphertext, ZkProofData}, + solana_zk_sdk::zk_elgamal_proof_program::proof_data::{ + ZeroCiphertextProofDataExt, ZkProofData, + }, + solana_zk_sdk_pod::proof_data::zero_ciphertext, wasm_bindgen::prelude::*, }; diff --git a/zk-sdk/src/lib.rs b/zk-sdk/src/lib.rs index 36e14d6..10762a5 100644 --- a/zk-sdk/src/lib.rs +++ b/zk-sdk/src/lib.rs @@ -21,7 +21,6 @@ pub mod encryption; pub mod errors; -pub mod pod; mod range_proof; mod sigma_proofs; #[cfg(not(target_os = "solana"))] diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index fd44f4d..884a19b 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -6,13 +6,13 @@ //! grouped-ciphertext validity proofs. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ - encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + encryption::elgamal::PodElGamalPubkey, + proof_data::batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext2HandlesValidityProofContext, + BatchedGroupedCiphertext2HandlesValidityProofData, }, - sigma_proofs::PodBatchedGroupedCiphertext2HandlesValidityProof, }, }; #[cfg(not(target_os = "solana"))] @@ -29,35 +29,27 @@ use { merlin::Transcript, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyBatchedGroupedCiphertextValidity` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedGroupedCiphertext2HandlesValidityProofData { - pub context: BatchedGroupedCiphertext2HandlesValidityProofContext, - - pub proof: PodBatchedGroupedCiphertext2HandlesValidityProof, -} - -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedGroupedCiphertext2HandlesValidityProofContext { - pub first_pubkey: PodElGamalPubkey, // 32 bytes - - pub second_pubkey: PodElGamalPubkey, // 32 bytes - - pub grouped_ciphertext_lo: PodGroupedElGamalCiphertext2Handles, // 96 bytes - - pub grouped_ciphertext_hi: PodGroupedElGamalCiphertext2Handles, // 96 bytes +pub trait BatchedGroupedCiphertext2HandlesValidityProofDataExt { + fn new( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + grouped_ciphertext_lo: &GroupedElGamalCiphertext<2>, + grouped_ciphertext_hi: &GroupedElGamalCiphertext<2>, + amount_lo: u64, + amount_hi: u64, + opening_lo: &PedersenOpening, + opening_hi: &PedersenOpening, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl BatchedGroupedCiphertext2HandlesValidityProofData { +impl BatchedGroupedCiphertext2HandlesValidityProofDataExt + for BatchedGroupedCiphertext2HandlesValidityProofData +{ #[allow(clippy::too_many_arguments)] - pub fn new( + fn new( first_pubkey: &ElGamalPubkey, second_pubkey: &ElGamalPubkey, grouped_ciphertext_lo: &GroupedElGamalCiphertext<2>, @@ -141,7 +133,7 @@ impl ZkProofData } #[cfg(not(target_os = "solana"))] -impl BatchedGroupedCiphertext2HandlesValidityProofContext { +impl ProofContext for BatchedGroupedCiphertext2HandlesValidityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"batched-grouped-ciphertext-validity-2-handles-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs index ef26f06..796368d 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -6,13 +6,13 @@ //! grouped-ciphertext validity proofs. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ - encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + encryption::elgamal::PodElGamalPubkey, + proof_data::batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext3HandlesValidityProofContext, + BatchedGroupedCiphertext3HandlesValidityProofData, }, - sigma_proofs::PodBatchedGroupedCiphertext3HandlesValidityProof, }, }; #[cfg(not(target_os = "solana"))] @@ -29,37 +29,29 @@ use { merlin::Transcript, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedGroupedCiphertext3HandlesValidityProofData { - pub context: BatchedGroupedCiphertext3HandlesValidityProofContext, - - pub proof: PodBatchedGroupedCiphertext3HandlesValidityProof, -} - -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedGroupedCiphertext3HandlesValidityProofContext { - pub first_pubkey: PodElGamalPubkey, // 32 bytes - - pub second_pubkey: PodElGamalPubkey, // 32 bytes - - pub third_pubkey: PodElGamalPubkey, // 32 bytes - - pub grouped_ciphertext_lo: PodGroupedElGamalCiphertext3Handles, // 128 bytes - - pub grouped_ciphertext_hi: PodGroupedElGamalCiphertext3Handles, // 128 bytes +pub trait BatchedGroupedCiphertext3HandlesValidityProofDataExt { + #[allow(clippy::too_many_arguments)] + fn new( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + third_pubkey: &ElGamalPubkey, + grouped_ciphertext_lo: &GroupedElGamalCiphertext<3>, + grouped_ciphertext_hi: &GroupedElGamalCiphertext<3>, + amount_lo: u64, + amount_hi: u64, + opening_lo: &PedersenOpening, + opening_hi: &PedersenOpening, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl BatchedGroupedCiphertext3HandlesValidityProofData { +impl BatchedGroupedCiphertext3HandlesValidityProofDataExt + for BatchedGroupedCiphertext3HandlesValidityProofData +{ #[allow(clippy::too_many_arguments)] - pub fn new( + fn new( first_pubkey: &ElGamalPubkey, second_pubkey: &ElGamalPubkey, third_pubkey: &ElGamalPubkey, @@ -153,7 +145,7 @@ impl ZkProofData } #[cfg(not(target_os = "solana"))] -impl BatchedGroupedCiphertext3HandlesValidityProofContext { +impl ProofContext for BatchedGroupedCiphertext3HandlesValidityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"batched-grouped-ciphertext-validity-3-handles-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs index 70d2a7e..b479bf1 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs @@ -2,12 +2,6 @@ mod handles_2; mod handles_3; pub use { - handles_2::{ - BatchedGroupedCiphertext2HandlesValidityProofContext, - BatchedGroupedCiphertext2HandlesValidityProofData, - }, - handles_3::{ - BatchedGroupedCiphertext3HandlesValidityProofContext, - BatchedGroupedCiphertext3HandlesValidityProofData, - }, + handles_2::BatchedGroupedCiphertext2HandlesValidityProofDataExt, + handles_3::BatchedGroupedCiphertext3HandlesValidityProofDataExt, }; diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs index 2385f63..49e263f 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs @@ -1,11 +1,11 @@ //! The 128-bit batched range proof instruction. use { - crate::zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::{ + proof_data::batched_range_proof::{BatchedRangeProofContext, BatchedRangeProofU128Data}, + range_proof::PodRangeProofU128, }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::range_proof::PodRangeProofU128, }; #[cfg(not(target_os = "solana"))] use { @@ -14,30 +14,29 @@ use { range_proof::RangeProof, zk_elgamal_proof_program::{ errors::{ProofGenerationError, ProofVerificationError}, - proof_data::batched_range_proof::MAX_COMMITMENTS, + proof_data::{ + batched_range_proof::{BatchedRangeProofContextExt, MAX_COMMITMENTS}, + ProofContext, + }, }, }, std::convert::TryInto, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyBatchedRangeProofU128` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedRangeProofU128Data { - /// The context data for a batched range proof - pub context: BatchedRangeProofContext, - - /// The batched range proof - pub proof: PodRangeProofU128, +pub trait BatchedRangeProofU128DataExt { + fn new( + commitments: Vec<&PedersenCommitment>, + amounts: Vec, + bit_lengths: Vec, + openings: Vec<&PedersenOpening>, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl BatchedRangeProofU128Data { - pub fn new( +impl BatchedRangeProofU128DataExt for BatchedRangeProofU128Data { + fn new( commitments: Vec<&PedersenCommitment>, amounts: Vec, bit_lengths: Vec, @@ -79,7 +78,7 @@ impl ZkProofData for BatchedRangeProofU128Data { #[cfg(not(target_os = "solana"))] fn verify_proof(&self) -> Result<(), ProofVerificationError> { - let (commitments, bit_lengths) = self.context.try_into()?; + let (commitments, bit_lengths) = self.context.try_into_commitment_bit_lengths_vec()?; let num_commitments = commitments.len(); if num_commitments > MAX_COMMITMENTS { diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs index e5e73e8..e0c3e76 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs @@ -1,11 +1,10 @@ //! The 256-bit batched range proof instruction. use { - crate::zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::batched_range_proof::{ + BatchedRangeProofContext, BatchedRangeProofU256Data, }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::range_proof::PodRangeProofU256, }; #[cfg(not(target_os = "solana"))] use { @@ -14,7 +13,12 @@ use { range_proof::RangeProof, zk_elgamal_proof_program::{ errors::{ProofGenerationError, ProofVerificationError}, - proof_data::batched_range_proof::{MAX_COMMITMENTS, MAX_SINGLE_BIT_LENGTH}, + proof_data::{ + batched_range_proof::{ + BatchedRangeProofContextExt, MAX_COMMITMENTS, MAX_SINGLE_BIT_LENGTH, + }, + ProofContext, + }, }, }, std::convert::TryInto, @@ -23,24 +27,20 @@ use { #[cfg(not(target_os = "solana"))] const BATCHED_RANGE_PROOF_U256_BIT_LENGTH: usize = 256; -/// The instruction data that is needed for the -/// `ProofInstruction::BatchedRangeProofU256Data` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedRangeProofU256Data { - /// The context data for a batched range proof - pub context: BatchedRangeProofContext, - - /// The batched range proof - pub proof: PodRangeProofU256, +pub trait BatchedRangeProofU256DataExt { + fn new( + commitments: Vec<&PedersenCommitment>, + amounts: Vec, + bit_lengths: Vec, + openings: Vec<&PedersenOpening>, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl BatchedRangeProofU256Data { - pub fn new( +impl BatchedRangeProofU256DataExt for BatchedRangeProofU256Data { + fn new( commitments: Vec<&PedersenCommitment>, amounts: Vec, bit_lengths: Vec, @@ -86,7 +86,7 @@ impl ZkProofData for BatchedRangeProofU256Data { #[cfg(not(target_os = "solana"))] fn verify_proof(&self) -> Result<(), ProofVerificationError> { - let (commitments, bit_lengths) = self.context.try_into()?; + let (commitments, bit_lengths) = self.context.try_into_commitment_bit_lengths_vec()?; let num_commitments = commitments.len(); // This check is unique to the 256-bit proof. For 64-bit and 128-bit proofs, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs index fa239b5..95137d0 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs @@ -1,11 +1,10 @@ //! The 64-bit batched range proof instruction. use { - crate::zk_elgamal_proof_program::proof_data::{ - batched_range_proof::BatchedRangeProofContext, ProofType, ZkProofData, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::batched_range_proof::{ + BatchedRangeProofContext, BatchedRangeProofU64Data, }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::range_proof::PodRangeProofU64, }; #[cfg(not(target_os = "solana"))] use { @@ -14,30 +13,29 @@ use { range_proof::RangeProof, zk_elgamal_proof_program::{ errors::{ProofGenerationError, ProofVerificationError}, - proof_data::batched_range_proof::MAX_COMMITMENTS, + proof_data::{ + batched_range_proof::{BatchedRangeProofContextExt, MAX_COMMITMENTS}, + ProofContext, + }, }, }, std::convert::TryInto, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyBatchedRangeProofU64` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct BatchedRangeProofU64Data { - /// The context data for a batched range proof - pub context: BatchedRangeProofContext, - - /// The batched range proof - pub proof: PodRangeProofU64, +pub trait BatchedRangeProofU64DataExt { + fn new( + commitments: Vec<&PedersenCommitment>, + amounts: Vec, + bit_lengths: Vec, + openings: Vec<&PedersenOpening>, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl BatchedRangeProofU64Data { - pub fn new( +impl BatchedRangeProofU64DataExt for BatchedRangeProofU64Data { + fn new( commitments: Vec<&PedersenCommitment>, amounts: Vec, bit_lengths: Vec, @@ -78,7 +76,7 @@ impl ZkProofData for BatchedRangeProofU64Data { #[cfg(not(target_os = "solana"))] fn verify_proof(&self) -> Result<(), ProofVerificationError> { - let (commitments, bit_lengths) = self.context.try_into()?; + let (commitments, bit_lengths) = self.context.try_into_commitment_bit_lengths_vec()?; let num_commitments = commitments.len(); if num_commitments > MAX_COMMITMENTS { diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs index 0c6cbcd..71f986d 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs @@ -22,15 +22,20 @@ pub mod batched_range_proof_u256; pub mod batched_range_proof_u64; use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; + #[cfg(not(target_os = "solana"))] use { crate::{ encryption::pedersen::{PedersenCommitment, PedersenOpening}, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::{bytes_of, Zeroable}, curve25519_dalek::traits::IsIdentity, merlin::Transcript, + solana_zk_sdk_pod::proof_data::batched_range_proof::BatchedRangeProofContext, std::convert::TryInto, }; @@ -44,28 +49,24 @@ const MAX_COMMITMENTS: usize = 8; #[cfg(not(target_os = "solana"))] const MAX_SINGLE_BIT_LENGTH: usize = 128; -/// The context data needed to verify a range-proof for a Pedersen committed value. -/// -/// This struct holds the public information that a batched range proof certifies. It includes the -/// Pedersen commitments and their corresponding bit lengths. This context is shared by all -/// `VerifyBatchedRangeProof{N}` instructions. -#[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable)] -#[repr(C)] -pub struct BatchedRangeProofContext { - pub commitments: [PodPedersenCommitment; MAX_COMMITMENTS], - pub bit_lengths: [u8; MAX_COMMITMENTS], +pub trait BatchedRangeProofContextExt { + fn new( + commitments: &[&PedersenCommitment], + amounts: &[u64], + bit_lengths: &[usize], + openings: &[&PedersenOpening], + ) -> Result + where + Self: Sized; + + fn try_into_commitment_bit_lengths_vec( + &self, + ) -> Result<(Vec, Vec), ProofVerificationError>; } #[allow(non_snake_case)] #[cfg(not(target_os = "solana"))] -impl BatchedRangeProofContext { - fn new_transcript(&self) -> Transcript { - let mut transcript = Transcript::new(b"batched-range-proof-instruction"); - transcript.append_message(b"commitments", bytes_of(&self.commitments)); - transcript.append_message(b"bit-lengths", bytes_of(&self.bit_lengths)); - transcript - } - +impl BatchedRangeProofContextExt for BatchedRangeProofContext { fn new( commitments: &[&PedersenCommitment], amounts: &[u64], @@ -106,13 +107,10 @@ impl BatchedRangeProofContext { bit_lengths: pod_bit_lengths, }) } -} -#[cfg(not(target_os = "solana"))] -impl TryInto<(Vec, Vec)> for BatchedRangeProofContext { - type Error = ProofVerificationError; - - fn try_into(self) -> Result<(Vec, Vec), Self::Error> { + fn try_into_commitment_bit_lengths_vec( + &self, + ) -> Result<(Vec, Vec), ProofVerificationError> { let commitments = self .commitments .into_iter() @@ -131,3 +129,12 @@ impl TryInto<(Vec, Vec)> for BatchedRangeProofContext Ok((commitments, bit_lengths)) } } + +impl ProofContext for BatchedRangeProofContext { + fn new_transcript(&self) -> Transcript { + let mut transcript = Transcript::new(b"batched-range-proof-instruction"); + transcript.append_message(b"commitments", bytes_of(&self.commitments)); + transcript.append_message(b"bit-lengths", bytes_of(&self.bit_lengths)); + transcript + } +} diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs index ead53ac..cb2d407 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs @@ -6,11 +6,12 @@ //! used to generate the second ciphertext. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - sigma_proofs::PodCiphertextCiphertextEqualityProof, + proof_data::ciphertext_ciphertext_equality::{ + CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, + }, }, }; #[cfg(not(target_os = "solana"))] @@ -28,35 +29,22 @@ use { std::convert::TryInto, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct CiphertextCiphertextEqualityProofData { - pub context: CiphertextCiphertextEqualityProofContext, - - pub proof: PodCiphertextCiphertextEqualityProof, -} - -/// The context data needed to verify a ciphertext-ciphertext equality proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct CiphertextCiphertextEqualityProofContext { - pub first_pubkey: PodElGamalPubkey, // 32 bytes - - pub second_pubkey: PodElGamalPubkey, // 32 bytes - - pub first_ciphertext: PodElGamalCiphertext, // 64 bytes - - pub second_ciphertext: PodElGamalCiphertext, // 64 bytes +pub trait CiphertextCiphertextEqualityProofDataExt { + fn new( + first_keypair: &ElGamalKeypair, + second_pubkey: &ElGamalPubkey, + first_ciphertext: &ElGamalCiphertext, + second_ciphertext: &ElGamalCiphertext, + second_opening: &PedersenOpening, + amount: u64, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl CiphertextCiphertextEqualityProofData { - pub fn new( +impl CiphertextCiphertextEqualityProofDataExt for CiphertextCiphertextEqualityProofData { + fn new( first_keypair: &ElGamalKeypair, second_pubkey: &ElGamalPubkey, first_ciphertext: &ElGamalCiphertext, @@ -125,7 +113,7 @@ impl ZkProofData #[allow(non_snake_case)] #[cfg(not(target_os = "solana"))] -impl CiphertextCiphertextEqualityProofContext { +impl ProofContext for CiphertextCiphertextEqualityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"ciphertext-ciphertext-equality-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs index 1e7d6c3..50c1577 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs @@ -6,14 +6,15 @@ //! key for the first ciphertext and the Pedersen opening for the commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ encryption::{ elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, pedersen::PodPedersenCommitment, }, - sigma_proofs::PodCiphertextCommitmentEqualityProof, + proof_data::ciphertext_commitment_equality::{ + CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, + }, }, }; #[cfg(not(target_os = "solana"))] @@ -30,35 +31,22 @@ use { merlin::Transcript, std::convert::TryInto, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct CiphertextCommitmentEqualityProofData { - pub context: CiphertextCommitmentEqualityProofContext, - pub proof: PodCiphertextCommitmentEqualityProof, -} - -/// The context data needed to verify a ciphertext-commitment equality proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct CiphertextCommitmentEqualityProofContext { - /// The ElGamal pubkey - pub pubkey: PodElGamalPubkey, // 32 bytes - /// The ciphertext encrypted under the ElGamal pubkey - pub ciphertext: PodElGamalCiphertext, // 64 bytes - - /// The Pedersen commitment - pub commitment: PodPedersenCommitment, // 32 bytes +pub trait CiphertextCommitmentEqualityProofDataExt { + fn new( + keypair: &ElGamalKeypair, + ciphertext: &ElGamalCiphertext, + commitment: &PedersenCommitment, + opening: &PedersenOpening, + amount: u64, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl CiphertextCommitmentEqualityProofData { - pub fn new( +impl CiphertextCommitmentEqualityProofDataExt for CiphertextCommitmentEqualityProofData { + fn new( keypair: &ElGamalKeypair, ciphertext: &ElGamalCiphertext, commitment: &PedersenCommitment, @@ -111,7 +99,7 @@ impl ZkProofData #[allow(non_snake_case)] #[cfg(not(target_os = "solana"))] -impl CiphertextCommitmentEqualityProofContext { +impl ProofContext for CiphertextCommitmentEqualityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"ciphertext-commitment-equality-instruction"); transcript.append_message(b"pubkey", bytes_of(&self.pubkey)); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs index c83d239..7d5addb 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -6,13 +6,13 @@ //! associated with the grouped ciphertext's commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ - encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext2Handles, + encryption::elgamal::PodElGamalPubkey, + proof_data::grouped_ciphertext_validity::{ + GroupedCiphertext2HandlesValidityProofContext, + GroupedCiphertext2HandlesValidityProofData, }, - sigma_proofs::PodGroupedCiphertext2HandlesValidityProof, }, }; #[cfg(not(target_os = "solana"))] @@ -29,32 +29,21 @@ use { merlin::Transcript, }; -/// The instruction data that is needed for the `ProofInstruction::VerifyGroupedCiphertextValidity` -/// instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct GroupedCiphertext2HandlesValidityProofData { - pub context: GroupedCiphertext2HandlesValidityProofContext, - - pub proof: PodGroupedCiphertext2HandlesValidityProof, -} - -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct GroupedCiphertext2HandlesValidityProofContext { - pub first_pubkey: PodElGamalPubkey, // 32 bytes - - pub second_pubkey: PodElGamalPubkey, // 32 bytes - - pub grouped_ciphertext: PodGroupedElGamalCiphertext2Handles, // 96 bytes +pub trait GroupedCiphertext2HandlesValidityProofDataExt { + fn new( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + grouped_ciphertext: &GroupedElGamalCiphertext<2>, + amount: u64, + opening: &PedersenOpening, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl GroupedCiphertext2HandlesValidityProofData { - pub fn new( +impl GroupedCiphertext2HandlesValidityProofDataExt for GroupedCiphertext2HandlesValidityProofData { + fn new( first_pubkey: &ElGamalPubkey, second_pubkey: &ElGamalPubkey, grouped_ciphertext: &GroupedElGamalCiphertext<2>, @@ -123,7 +112,7 @@ impl ZkProofData } #[cfg(not(target_os = "solana"))] -impl GroupedCiphertext2HandlesValidityProofContext { +impl ProofContext for GroupedCiphertext2HandlesValidityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"grouped-ciphertext-validity-2-handles-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs index f534b58..38baa00 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -6,13 +6,13 @@ //! associated with the grouped ciphertext's commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ - encryption::{ - elgamal::PodElGamalPubkey, grouped_elgamal::PodGroupedElGamalCiphertext3Handles, + encryption::elgamal::PodElGamalPubkey, + proof_data::grouped_ciphertext_validity::{ + GroupedCiphertext3HandlesValidityProofContext, + GroupedCiphertext3HandlesValidityProofData, }, - sigma_proofs::PodGroupedCiphertext3HandlesValidityProof, }, }; #[cfg(not(target_os = "solana"))] @@ -29,34 +29,22 @@ use { merlin::Transcript, }; -/// The instruction data that is needed for the -/// `ProofInstruction::VerifyGroupedCiphertext3HandlesValidity` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct GroupedCiphertext3HandlesValidityProofData { - pub context: GroupedCiphertext3HandlesValidityProofContext, - - pub proof: PodGroupedCiphertext3HandlesValidityProof, -} - -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct GroupedCiphertext3HandlesValidityProofContext { - pub first_pubkey: PodElGamalPubkey, // 32 bytes - - pub second_pubkey: PodElGamalPubkey, // 32 bytes - - pub third_pubkey: PodElGamalPubkey, // 32 bytes - - pub grouped_ciphertext: PodGroupedElGamalCiphertext3Handles, // 128 bytes +pub trait GroupedCiphertext3HandlesValidityProofDataExt { + fn new( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + third_pubkey: &ElGamalPubkey, + grouped_ciphertext: &GroupedElGamalCiphertext<3>, + amount: u64, + opening: &PedersenOpening, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl GroupedCiphertext3HandlesValidityProofData { - pub fn new( +impl GroupedCiphertext3HandlesValidityProofDataExt for GroupedCiphertext3HandlesValidityProofData { + fn new( first_pubkey: &ElGamalPubkey, second_pubkey: &ElGamalPubkey, third_pubkey: &ElGamalPubkey, @@ -133,7 +121,7 @@ impl ZkProofData } #[cfg(not(target_os = "solana"))] -impl GroupedCiphertext3HandlesValidityProofContext { +impl ProofContext for GroupedCiphertext3HandlesValidityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"grouped-ciphertext-validity-3-handles-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs index 7f1149b..89b25cb 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs @@ -2,10 +2,6 @@ mod handles_2; mod handles_3; pub use { - handles_2::{ - GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, - }, - handles_3::{ - GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, - }, + handles_2::GroupedCiphertext2HandlesValidityProofDataExt, + handles_3::GroupedCiphertext3HandlesValidityProofDataExt, }; diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs index 3d061bd..4aa7e5e 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs @@ -1,5 +1,5 @@ #[cfg(not(target_os = "solana"))] -use crate::zk_elgamal_proof_program::errors::ProofVerificationError; +use {crate::zk_elgamal_proof_program::errors::ProofVerificationError, merlin::Transcript}; use { bytemuck::Pod, num_derive::{FromPrimitive, ToPrimitive}, @@ -18,29 +18,51 @@ pub mod zero_ciphertext; pub use { batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext2HandlesValidityProofContext, - BatchedGroupedCiphertext2HandlesValidityProofData, - BatchedGroupedCiphertext3HandlesValidityProofContext, - BatchedGroupedCiphertext3HandlesValidityProofData, + BatchedGroupedCiphertext2HandlesValidityProofDataExt, + BatchedGroupedCiphertext3HandlesValidityProofDataExt, }, batched_range_proof::{ - batched_range_proof_u128::BatchedRangeProofU128Data, - batched_range_proof_u256::BatchedRangeProofU256Data, - batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, - }, - ciphertext_ciphertext_equality::{ - CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, - }, - ciphertext_commitment_equality::{ - CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, + batched_range_proof_u128::BatchedRangeProofU128DataExt, + batched_range_proof_u256::BatchedRangeProofU256DataExt, + batched_range_proof_u64::BatchedRangeProofU64DataExt, BatchedRangeProofContextExt, }, + ciphertext_ciphertext_equality::CiphertextCiphertextEqualityProofDataExt, + ciphertext_commitment_equality::CiphertextCommitmentEqualityProofDataExt, grouped_ciphertext_validity::{ - GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, - GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, + GroupedCiphertext2HandlesValidityProofDataExt, + GroupedCiphertext3HandlesValidityProofDataExt, + }, + percentage_with_cap::PercentageWithCapProofDataExt, + pubkey_validity::PubkeyValidityProofDataExt, + solana_zk_sdk_pod::proof_data::{ + batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext2HandlesValidityProofContext, + BatchedGroupedCiphertext2HandlesValidityProofData, + BatchedGroupedCiphertext3HandlesValidityProofContext, + BatchedGroupedCiphertext3HandlesValidityProofData, + }, + batched_range_proof::{ + batched_range_proof_u128::BatchedRangeProofU128Data, + batched_range_proof_u256::BatchedRangeProofU256Data, + batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, + }, + ciphertext_ciphertext_equality::{ + CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, + }, + ciphertext_commitment_equality::{ + CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, + }, + grouped_ciphertext_validity::{ + GroupedCiphertext2HandlesValidityProofContext, + GroupedCiphertext2HandlesValidityProofData, + GroupedCiphertext3HandlesValidityProofContext, + GroupedCiphertext3HandlesValidityProofData, + }, + percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, + pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, + zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, }, - percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, - pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, - zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, + zero_ciphertext::ZeroCiphertextProofDataExt, }; #[derive(Clone, Copy, Debug, FromPrimitive, ToPrimitive, PartialEq, Eq)] @@ -70,3 +92,7 @@ pub trait ZkProofData { #[cfg(not(target_os = "solana"))] fn verify_proof(&self) -> Result<(), ProofVerificationError>; } + +trait ProofContext { + fn new_transcript(&self) -> Transcript; +} diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs index f96fedc..29fc3b2 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs @@ -6,6 +6,15 @@ //! - the `percentage` amount is equal to a constant (referred to as the `max_value`) //! - the `delta` and `claimed` amounts are equal +use { + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, + solana_zk_sdk_pod::{ + encryption::pedersen::PodPedersenCommitment, + proof_data::percentage_with_cap::{ + PercentageWithCapProofContext, PercentageWithCapProofData, + }, + }, +}; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -17,56 +26,28 @@ use { merlin::Transcript, std::convert::TryInto, }; -use { - crate::{ - pod::PodU64, - zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - }, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::{ - encryption::pedersen::PodPedersenCommitment, sigma_proofs::PodPercentageWithCapProof, - }, -}; - -/// The instruction data that is needed for the `ProofInstruction::VerifyPercentageWithCap` -/// instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct PercentageWithCapProofData { - pub context: PercentageWithCapProofContext, - - pub proof: PodPercentageWithCapProof, -} -/// The context data needed to verify a percentage-with-cap proof. -/// -/// We refer to [`ZK ElGamal proof`] for the formal details on how the percentage-with-cap proof is -/// computed. -/// -/// [`ZK ElGamal proof`]: https://docs.solanalabs.com/runtime/zk-token-proof -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct PercentageWithCapProofContext { - /// The Pedersen commitment to the percentage amount. - pub percentage_commitment: PodPedersenCommitment, - - /// The Pedersen commitment to the delta amount. - pub delta_commitment: PodPedersenCommitment, - - /// The Pedersen commitment to the claimed amount. - pub claimed_commitment: PodPedersenCommitment, - - /// The maximum cap bound. - pub max_value: PodU64, +pub trait PercentageWithCapProofDataExt { + #[allow(clippy::too_many_arguments)] + fn new( + percentage_commitment: &PedersenCommitment, + percentage_opening: &PedersenOpening, + percentage_amount: u64, + delta_commitment: &PedersenCommitment, + delta_opening: &PedersenOpening, + delta_amount: u64, + claimed_commitment: &PedersenCommitment, + claimed_opening: &PedersenOpening, + max_value: u64, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl PercentageWithCapProofData { +impl PercentageWithCapProofDataExt for PercentageWithCapProofData { #[allow(clippy::too_many_arguments)] - pub fn new( + fn new( percentage_commitment: &PedersenCommitment, percentage_opening: &PedersenOpening, percentage_amount: u64, @@ -139,7 +120,7 @@ impl ZkProofData for PercentageWithCapProofData { } #[cfg(not(target_os = "solana"))] -impl PercentageWithCapProofContext { +impl ProofContext for PercentageWithCapProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"percentage-with-cap-instruction"); transcript.append_message( diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs index fd160ba..e46f3d0 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs @@ -6,10 +6,10 @@ //! public key. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, sigma_proofs::PodPubkeyValidityProof, + encryption::elgamal::PodElGamalPubkey, + proof_data::pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, }, }; #[cfg(not(target_os = "solana"))] @@ -24,32 +24,15 @@ use { std::convert::TryInto, }; -/// The instruction data that is needed for the `ProofInstruction::VerifyPubkeyValidity` -/// instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct PubkeyValidityProofData { - /// The context data for the public key validity proof - pub context: PubkeyValidityProofContext, // 32 bytes - - /// Proof that the public key is well-formed - pub proof: PodPubkeyValidityProof, // 64 bytes -} - -/// The context data needed to verify a pubkey validity proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct PubkeyValidityProofContext { - /// The public key to be proved - pub pubkey: PodElGamalPubkey, // 32 bytes +pub trait PubkeyValidityProofDataExt { + fn new(keypair: &ElGamalKeypair) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl PubkeyValidityProofData { - pub fn new(keypair: &ElGamalKeypair) -> Result { +impl PubkeyValidityProofDataExt for PubkeyValidityProofData { + fn new(keypair: &ElGamalKeypair) -> Result { let pod_pubkey = PodElGamalPubkey(keypair.pubkey().into()); let context = PubkeyValidityProofContext { pubkey: pod_pubkey }; @@ -79,7 +62,7 @@ impl ZkProofData for PubkeyValidityProofData { #[allow(non_snake_case)] #[cfg(not(target_os = "solana"))] -impl PubkeyValidityProofContext { +impl ProofContext for PubkeyValidityProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"pubkey-validity-instruction"); transcript.append_message(b"pubkey", bytes_of(&self.pubkey)); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs index 3a0b7e6..20eef68 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs @@ -5,11 +5,10 @@ //! generate the proof, a prover must provide the decryption key for the ciphertext. use { - crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - bytemuck_derive::{Pod, Zeroable}, - solana_zk_sdk_pod::{ - encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - sigma_proofs::PodZeroCiphertextProof, + crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + solana_zk_sdk_pod::proof_data::zero_ciphertext::{ + ZeroCiphertextProofContext, ZeroCiphertextProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -24,34 +23,18 @@ use { std::convert::TryInto, }; -/// The instruction data that is needed for the `ProofInstruction::VerifyZeroCiphertext` instruction. -/// -/// It includes the cryptographic proof as well as the context data information needed to verify -/// the proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct ZeroCiphertextProofData { - /// The context data for the zero-ciphertext proof - pub context: ZeroCiphertextProofContext, // 96 bytes - - /// Proof that the ciphertext is zero - pub proof: PodZeroCiphertextProof, // 96 bytes -} - -/// The context data needed to verify a zero-ciphertext proof. -#[derive(Clone, Copy, Pod, Zeroable)] -#[repr(C)] -pub struct ZeroCiphertextProofContext { - /// The ElGamal pubkey associated with the ElGamal ciphertext - pub pubkey: PodElGamalPubkey, // 32 bytes - - /// The ElGamal ciphertext that encrypts zero - pub ciphertext: PodElGamalCiphertext, // 64 bytes +pub trait ZeroCiphertextProofDataExt { + fn new( + keypair: &ElGamalKeypair, + ciphertext: &ElGamalCiphertext, + ) -> Result + where + Self: Sized; } #[cfg(not(target_os = "solana"))] -impl ZeroCiphertextProofData { - pub fn new( +impl ZeroCiphertextProofDataExt for ZeroCiphertextProofData { + fn new( keypair: &ElGamalKeypair, ciphertext: &ElGamalCiphertext, ) -> Result { @@ -91,7 +74,7 @@ impl ZkProofData for ZeroCiphertextProofData { #[allow(non_snake_case)] #[cfg(not(target_os = "solana"))] -impl ZeroCiphertextProofContext { +impl ProofContext for ZeroCiphertextProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"zero-ciphertext-instruction"); From d39b621ac57c3fcc7e4f0a4302e64e8816c55bb6 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 28 Oct 2025 11:15:18 +0900 Subject: [PATCH 6/7] cargo fmt and clippy --- zk-sdk/src/sigma_proofs/mod.rs | 1 - .../batched_grouped_ciphertext_validity/handles_2.rs | 1 + .../proof_data/batched_range_proof/mod.rs | 1 - .../zk_elgamal_proof_program/proof_data/zero_ciphertext.rs | 6 +++--- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/zk-sdk/src/sigma_proofs/mod.rs b/zk-sdk/src/sigma_proofs/mod.rs index 3d3eddc..abc2263 100644 --- a/zk-sdk/src/sigma_proofs/mod.rs +++ b/zk-sdk/src/sigma_proofs/mod.rs @@ -32,7 +32,6 @@ pub use solana_zk_sdk_pod::sigma_proofs::{ GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN, PERCENTAGE_WITH_CAP_PROOF_LEN, PUBKEY_VALIDITY_PROOF_LEN, ZERO_CIPHERTEXT_PROOF_LEN, }; - #[cfg(not(target_os = "solana"))] use { crate::{ diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index 884a19b..d8b72a2 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -30,6 +30,7 @@ use { }; pub trait BatchedGroupedCiphertext2HandlesValidityProofDataExt { + #[allow(clippy::too_many_arguments)] fn new( first_pubkey: &ElGamalPubkey, second_pubkey: &ElGamalPubkey, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs index 71f986d..3df2c72 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs @@ -22,7 +22,6 @@ pub mod batched_range_proof_u256; pub mod batched_range_proof_u64; use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; - #[cfg(not(target_os = "solana"))] use { crate::{ diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs index 20eef68..88f2b89 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs @@ -6,9 +6,9 @@ use { crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - solana_zk_sdk_pod::proof_data::zero_ciphertext::{ - ZeroCiphertextProofContext, ZeroCiphertextProofData, + solana_zk_sdk_pod::{ + encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + proof_data::zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, }, }; #[cfg(not(target_os = "solana"))] From bbb0546ba0fe1f72b54c763ca71436e1ea9af6a5 Mon Sep 17 00:00:00 2001 From: Sam Kim Date: Tue, 28 Oct 2025 11:44:59 +0900 Subject: [PATCH 7/7] fix sbf visibililty --- zk-sdk/src/encryption/mod.rs | 1 - zk-sdk/src/encryption/pod/auth_encryption.rs | 3 - zk-sdk/src/encryption/pod/elgamal.rs | 3 - zk-sdk/src/encryption/pod/grouped_elgamal.rs | 3 - zk-sdk/src/encryption/pod/mod.rs | 4 - zk-sdk/src/encryption/pod/pedersen.rs | 3 - zk-sdk/src/range_proof/mod.rs | 1 + zk-sdk/src/range_proof/pod.rs | 187 ------------------ .../handles_2.rs | 18 +- .../handles_3.rs | 18 +- .../mod.rs | 1 + .../batched_range_proof_u128.rs | 7 +- .../batched_range_proof_u256.rs | 1 + .../batched_range_proof_u64.rs | 1 + .../proof_data/batched_range_proof/mod.rs | 9 +- .../ciphertext_ciphertext_equality.rs | 16 +- .../ciphertext_commitment_equality.rs | 22 ++- .../grouped_ciphertext_validity/handles_2.rs | 17 +- .../grouped_ciphertext_validity/handles_3.rs | 17 +- .../grouped_ciphertext_validity/mod.rs | 1 + .../proof_data/mod.rs | 56 +++--- .../proof_data/percentage_with_cap.rs | 16 +- .../proof_data/pubkey_validity.rs | 14 +- .../proof_data/zero_ciphertext.rs | 14 +- 24 files changed, 130 insertions(+), 303 deletions(-) delete mode 100644 zk-sdk/src/encryption/pod/auth_encryption.rs delete mode 100644 zk-sdk/src/encryption/pod/elgamal.rs delete mode 100644 zk-sdk/src/encryption/pod/grouped_elgamal.rs delete mode 100644 zk-sdk/src/encryption/pod/mod.rs delete mode 100644 zk-sdk/src/encryption/pod/pedersen.rs delete mode 100644 zk-sdk/src/range_proof/pod.rs diff --git a/zk-sdk/src/encryption/mod.rs b/zk-sdk/src/encryption/mod.rs index 8cad621..a8d0cd8 100644 --- a/zk-sdk/src/encryption/mod.rs +++ b/zk-sdk/src/encryption/mod.rs @@ -25,7 +25,6 @@ pub mod elgamal; pub mod grouped_elgamal; #[cfg(not(target_os = "solana"))] pub mod pedersen; -pub mod pod; /// Byte length of an authenticated encryption secret key pub const AE_KEY_LEN: usize = 16; diff --git a/zk-sdk/src/encryption/pod/auth_encryption.rs b/zk-sdk/src/encryption/pod/auth_encryption.rs deleted file mode 100644 index e1d2336..0000000 --- a/zk-sdk/src/encryption/pod/auth_encryption.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Plain Old Data types for the AES128-GCM-SIV authenticated encryption scheme. - -pub use solana_zk_sdk_pod::encryption::auth_encryption::*; diff --git a/zk-sdk/src/encryption/pod/elgamal.rs b/zk-sdk/src/encryption/pod/elgamal.rs deleted file mode 100644 index c21d5d1..0000000 --- a/zk-sdk/src/encryption/pod/elgamal.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Plain Old Data types for the ElGamal encryption scheme. - -pub use solana_zk_sdk_pod::encryption::elgamal::*; diff --git a/zk-sdk/src/encryption/pod/grouped_elgamal.rs b/zk-sdk/src/encryption/pod/grouped_elgamal.rs deleted file mode 100644 index 0c08b70..0000000 --- a/zk-sdk/src/encryption/pod/grouped_elgamal.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Plain Old Data types for the Grouped ElGamal encryption scheme. - -pub use solana_zk_sdk_pod::encryption::grouped_elgamal::*; diff --git a/zk-sdk/src/encryption/pod/mod.rs b/zk-sdk/src/encryption/pod/mod.rs deleted file mode 100644 index 90305a4..0000000 --- a/zk-sdk/src/encryption/pod/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod auth_encryption; -pub mod elgamal; -pub mod grouped_elgamal; -pub mod pedersen; diff --git a/zk-sdk/src/encryption/pod/pedersen.rs b/zk-sdk/src/encryption/pod/pedersen.rs deleted file mode 100644 index feedcb6..0000000 --- a/zk-sdk/src/encryption/pod/pedersen.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Plain Old Data type for the Pedersen commitment scheme. - -pub use solana_zk_sdk_pod::encryption::pedersen::*; diff --git a/zk-sdk/src/range_proof/mod.rs b/zk-sdk/src/range_proof/mod.rs index 745a804..d83e1e4 100644 --- a/zk-sdk/src/range_proof/mod.rs +++ b/zk-sdk/src/range_proof/mod.rs @@ -48,6 +48,7 @@ pub mod inner_product; #[cfg(not(target_os = "solana"))] pub mod util; +#[cfg(not(target_os = "solana"))] pub use solana_zk_sdk_pod::range_proof::{ INNER_PRODUCT_PROOF_U128_LEN, INNER_PRODUCT_PROOF_U256_LEN, INNER_PRODUCT_PROOF_U64_LEN, RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN, RANGE_PROOF_U128_LEN, RANGE_PROOF_U256_LEN, diff --git a/zk-sdk/src/range_proof/pod.rs b/zk-sdk/src/range_proof/pod.rs deleted file mode 100644 index 2860408..0000000 --- a/zk-sdk/src/range_proof/pod.rs +++ /dev/null @@ -1,187 +0,0 @@ -//! Plain Old Data types for range proofs. - -#[cfg(not(target_os = "solana"))] -use crate::{ - range_proof::{errors::RangeProofVerificationError, RangeProof}, - UNIT_LEN, -}; -use { - crate::{ - pod::{impl_from_bytes, impl_from_str}, - range_proof::*, - }, - base64::{prelude::BASE64_STANDARD, Engine}, - bytemuck::{Pod, Zeroable}, - std::fmt, -}; - -/// The `RangeProof` type as a `Pod` restricted to proofs on 64-bit numbers. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct PodRangeProofU64(pub(crate) [u8; RANGE_PROOF_U64_LEN]); - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PodRangeProofU64 { - type Error = RangeProofVerificationError; - - fn try_from(decoded_proof: RangeProof) -> Result { - if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U64_LEN { - return Err(RangeProofVerificationError::Deserialization); - } - - let mut buf = [0_u8; RANGE_PROOF_U64_LEN]; - copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); - buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U64_LEN] - .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); - Ok(PodRangeProofU64(buf)) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for RangeProof { - type Error = RangeProofVerificationError; - - fn try_from(pod_proof: PodRangeProofU64) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - -const RANGE_PROOF_U64_MAX_BASE64_LEN: usize = 896; - -impl fmt::Display for PodRangeProofU64 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodRangeProofU64, - BYTES_LEN = RANGE_PROOF_U64_LEN, - BASE64_LEN = RANGE_PROOF_U64_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodRangeProofU64, BYTES_LEN = RANGE_PROOF_U64_LEN); - -/// The `RangeProof` type as a `Pod` restricted to proofs on 128-bit numbers. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct PodRangeProofU128(pub(crate) [u8; RANGE_PROOF_U128_LEN]); - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PodRangeProofU128 { - type Error = RangeProofVerificationError; - - fn try_from(decoded_proof: RangeProof) -> Result { - if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U128_LEN { - return Err(RangeProofVerificationError::Deserialization); - } - - let mut buf = [0_u8; RANGE_PROOF_U128_LEN]; - copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); - buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U128_LEN] - .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); - Ok(PodRangeProofU128(buf)) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for RangeProof { - type Error = RangeProofVerificationError; - - fn try_from(pod_proof: PodRangeProofU128) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - -const RANGE_PROOF_U128_MAX_BASE64_LEN: usize = 984; - -impl fmt::Display for PodRangeProofU128 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodRangeProofU128, - BYTES_LEN = RANGE_PROOF_U128_LEN, - BASE64_LEN = RANGE_PROOF_U128_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodRangeProofU128, BYTES_LEN = RANGE_PROOF_U128_LEN); - -/// The `RangeProof` type as a `Pod` restricted to proofs on 256-bit numbers. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct PodRangeProofU256(pub(crate) [u8; RANGE_PROOF_U256_LEN]); - -#[cfg(not(target_os = "solana"))] -impl TryFrom for PodRangeProofU256 { - type Error = RangeProofVerificationError; - - fn try_from(decoded_proof: RangeProof) -> Result { - if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U256_LEN { - return Err(RangeProofVerificationError::Deserialization); - } - - let mut buf = [0_u8; RANGE_PROOF_U256_LEN]; - copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); - buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U256_LEN] - .copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); - Ok(PodRangeProofU256(buf)) - } -} - -#[cfg(not(target_os = "solana"))] -impl TryFrom for RangeProof { - type Error = RangeProofVerificationError; - - fn try_from(pod_proof: PodRangeProofU256) -> Result { - Self::from_bytes(&pod_proof.0) - } -} - -const RANGE_PROOF_U256_MAX_BASE64_LEN: usize = 1068; - -impl fmt::Display for PodRangeProofU256 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", BASE64_STANDARD.encode(self.0)) - } -} - -impl_from_str!( - TYPE = PodRangeProofU256, - BYTES_LEN = RANGE_PROOF_U256_LEN, - BASE64_LEN = RANGE_PROOF_U256_MAX_BASE64_LEN -); - -impl_from_bytes!(TYPE = PodRangeProofU256, BYTES_LEN = RANGE_PROOF_U256_LEN); - -#[cfg(not(target_os = "solana"))] -fn copy_range_proof_modulo_inner_product_proof(proof: &RangeProof, buf: &mut [u8]) { - let mut chunks = buf.chunks_mut(UNIT_LEN); - chunks.next().unwrap().copy_from_slice(proof.A.as_bytes()); - chunks.next().unwrap().copy_from_slice(proof.S.as_bytes()); - chunks.next().unwrap().copy_from_slice(proof.T_1.as_bytes()); - chunks.next().unwrap().copy_from_slice(proof.T_2.as_bytes()); - chunks.next().unwrap().copy_from_slice(proof.t_x.as_bytes()); - chunks - .next() - .unwrap() - .copy_from_slice(proof.t_x_blinding.as_bytes()); - chunks - .next() - .unwrap() - .copy_from_slice(proof.e_blinding.as_bytes()); -} - -// The range proof pod types are wrappers for byte arrays, which are both `Pod` and `Zeroable`. However, -// the marker traits `bytemuck::Pod` and `bytemuck::Zeroable` can only be derived for power-of-two -// length byte arrays. Directly implement these traits for the range proof pod types. -unsafe impl Zeroable for PodRangeProofU64 {} -unsafe impl Pod for PodRangeProofU64 {} - -unsafe impl Zeroable for PodRangeProofU128 {} -unsafe impl Pod for PodRangeProofU128 {} - -unsafe impl Zeroable for PodRangeProofU256 {} -unsafe impl Pod for PodRangeProofU256 {} diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs index d8b72a2..03a26ea 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_2.rs @@ -6,13 +6,10 @@ //! grouped-ciphertext validity proofs. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, - proof_data::batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext2HandlesValidityProofContext, - BatchedGroupedCiphertext2HandlesValidityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext2HandlesValidityProofContext, + BatchedGroupedCiphertext2HandlesValidityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -23,12 +20,17 @@ use { pedersen::PedersenOpening, }, sigma_proofs::batched_grouped_ciphertext_validity::BatchedGroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, }; +#[cfg(not(target_os = "solana"))] pub trait BatchedGroupedCiphertext2HandlesValidityProofDataExt { #[allow(clippy::too_many_arguments)] fn new( diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs index 796368d..39e4288 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/handles_3.rs @@ -6,13 +6,10 @@ //! grouped-ciphertext validity proofs. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, - proof_data::batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext3HandlesValidityProofContext, - BatchedGroupedCiphertext3HandlesValidityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext3HandlesValidityProofContext, + BatchedGroupedCiphertext3HandlesValidityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -23,12 +20,17 @@ use { pedersen::PedersenOpening, }, sigma_proofs::batched_grouped_ciphertext_validity::BatchedGroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, }; +#[cfg(not(target_os = "solana"))] pub trait BatchedGroupedCiphertext3HandlesValidityProofDataExt { #[allow(clippy::too_many_arguments)] fn new( diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs index b479bf1..4b88952 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_grouped_ciphertext_validity/mod.rs @@ -1,6 +1,7 @@ mod handles_2; mod handles_3; +#[cfg(not(target_os = "solana"))] pub use { handles_2::BatchedGroupedCiphertext2HandlesValidityProofDataExt, handles_3::BatchedGroupedCiphertext3HandlesValidityProofDataExt, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs index 49e263f..7e0403f 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u128.rs @@ -2,9 +2,8 @@ use { crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - proof_data::batched_range_proof::{BatchedRangeProofContext, BatchedRangeProofU128Data}, - range_proof::PodRangeProofU128, + solana_zk_sdk_pod::proof_data::batched_range_proof::{ + BatchedRangeProofContext, BatchedRangeProofU128Data, }, }; #[cfg(not(target_os = "solana"))] @@ -20,9 +19,11 @@ use { }, }, }, + solana_zk_sdk_pod::range_proof::PodRangeProofU128, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait BatchedRangeProofU128DataExt { fn new( commitments: Vec<&PedersenCommitment>, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs index e0c3e76..dc1dedf 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u256.rs @@ -27,6 +27,7 @@ use { #[cfg(not(target_os = "solana"))] const BATCHED_RANGE_PROOF_U256_BIT_LENGTH: usize = 256; +#[cfg(not(target_os = "solana"))] pub trait BatchedRangeProofU256DataExt { fn new( commitments: Vec<&PedersenCommitment>, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs index 95137d0..252e845 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/batched_range_proof_u64.rs @@ -22,6 +22,7 @@ use { std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait BatchedRangeProofU64DataExt { fn new( commitments: Vec<&PedersenCommitment>, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs index 3df2c72..0af68b4 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/batched_range_proof/mod.rs @@ -21,7 +21,6 @@ pub mod batched_range_proof_u128; pub mod batched_range_proof_u256; pub mod batched_range_proof_u64; -use solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -34,11 +33,15 @@ use { bytemuck::{bytes_of, Zeroable}, curve25519_dalek::traits::IsIdentity, merlin::Transcript, - solana_zk_sdk_pod::proof_data::batched_range_proof::BatchedRangeProofContext, + solana_zk_sdk_pod::{ + encryption::pedersen::PodPedersenCommitment, + proof_data::batched_range_proof::BatchedRangeProofContext, + }, std::convert::TryInto, }; /// The maximum number of Pedersen commitments that can be processed in a single batched range proof. +#[cfg(not(target_os = "solana"))] const MAX_COMMITMENTS: usize = 8; /// A bit length in a batched range proof must be at most 128. @@ -48,6 +51,7 @@ const MAX_COMMITMENTS: usize = 8; #[cfg(not(target_os = "solana"))] const MAX_SINGLE_BIT_LENGTH: usize = 128; +#[cfg(not(target_os = "solana"))] pub trait BatchedRangeProofContextExt { fn new( commitments: &[&PedersenCommitment], @@ -129,6 +133,7 @@ impl BatchedRangeProofContextExt for BatchedRangeProofContext { } } +#[cfg(not(target_os = "solana"))] impl ProofContext for BatchedRangeProofContext { fn new_transcript(&self) -> Transcript { let mut transcript = Transcript::new(b"batched-range-proof-instruction"); diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs index cb2d407..0d29efd 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_ciphertext_equality.rs @@ -6,12 +6,9 @@ //! used to generate the second ciphertext. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - proof_data::ciphertext_ciphertext_equality::{ - CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::ciphertext_ciphertext_equality::{ + CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -22,13 +19,18 @@ use { pedersen::PedersenOpening, }, sigma_proofs::ciphertext_ciphertext_equality::CiphertextCiphertextEqualityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait CiphertextCiphertextEqualityProofDataExt { fn new( first_keypair: &ElGamalKeypair, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs index 50c1577..2bf6493 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/ciphertext_commitment_equality.rs @@ -6,15 +6,9 @@ //! key for the first ciphertext and the Pedersen opening for the commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::{ - elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - pedersen::PodPedersenCommitment, - }, - proof_data::ciphertext_commitment_equality::{ - CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::ciphertext_commitment_equality::{ + CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -25,13 +19,21 @@ use { pedersen::{PedersenCommitment, PedersenOpening}, }, sigma_proofs::ciphertext_commitment_equality::CiphertextCommitmentEqualityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::{ + elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, + pedersen::PodPedersenCommitment, + }, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait CiphertextCommitmentEqualityProofDataExt { fn new( keypair: &ElGamalKeypair, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs index 7d5addb..c54a84d 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_2.rs @@ -6,13 +6,9 @@ //! associated with the grouped ciphertext's commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, - proof_data::grouped_ciphertext_validity::{ - GroupedCiphertext2HandlesValidityProofContext, - GroupedCiphertext2HandlesValidityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::grouped_ciphertext_validity::{ + GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -23,12 +19,17 @@ use { pedersen::PedersenOpening, }, sigma_proofs::grouped_ciphertext_validity::GroupedCiphertext2HandlesValidityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, }; +#[cfg(not(target_os = "solana"))] pub trait GroupedCiphertext2HandlesValidityProofDataExt { fn new( first_pubkey: &ElGamalPubkey, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs index 38baa00..f636a48 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/handles_3.rs @@ -6,13 +6,9 @@ //! associated with the grouped ciphertext's commitment. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, - proof_data::grouped_ciphertext_validity::{ - GroupedCiphertext3HandlesValidityProofContext, - GroupedCiphertext3HandlesValidityProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::grouped_ciphertext_validity::{ + GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -23,12 +19,17 @@ use { pedersen::PedersenOpening, }, sigma_proofs::grouped_ciphertext_validity::GroupedCiphertext3HandlesValidityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, }; +#[cfg(not(target_os = "solana"))] pub trait GroupedCiphertext3HandlesValidityProofDataExt { fn new( first_pubkey: &ElGamalPubkey, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs index 89b25cb..98230e1 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/grouped_ciphertext_validity/mod.rs @@ -1,6 +1,7 @@ mod handles_2; mod handles_3; +#[cfg(not(target_os = "solana"))] pub use { handles_2::GroupedCiphertext2HandlesValidityProofDataExt, handles_3::GroupedCiphertext3HandlesValidityProofDataExt, diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs index 4aa7e5e..785a763 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/mod.rs @@ -16,6 +16,33 @@ pub mod pod; pub mod pubkey_validity; pub mod zero_ciphertext; +pub use solana_zk_sdk_pod::proof_data::{ + batched_grouped_ciphertext_validity::{ + BatchedGroupedCiphertext2HandlesValidityProofContext, + BatchedGroupedCiphertext2HandlesValidityProofData, + BatchedGroupedCiphertext3HandlesValidityProofContext, + BatchedGroupedCiphertext3HandlesValidityProofData, + }, + batched_range_proof::{ + batched_range_proof_u128::BatchedRangeProofU128Data, + batched_range_proof_u256::BatchedRangeProofU256Data, + batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, + }, + ciphertext_ciphertext_equality::{ + CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, + }, + ciphertext_commitment_equality::{ + CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, + }, + grouped_ciphertext_validity::{ + GroupedCiphertext2HandlesValidityProofContext, GroupedCiphertext2HandlesValidityProofData, + GroupedCiphertext3HandlesValidityProofContext, GroupedCiphertext3HandlesValidityProofData, + }, + percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, + pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, + zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, +}; +#[cfg(not(target_os = "solana"))] pub use { batched_grouped_ciphertext_validity::{ BatchedGroupedCiphertext2HandlesValidityProofDataExt, @@ -34,34 +61,6 @@ pub use { }, percentage_with_cap::PercentageWithCapProofDataExt, pubkey_validity::PubkeyValidityProofDataExt, - solana_zk_sdk_pod::proof_data::{ - batched_grouped_ciphertext_validity::{ - BatchedGroupedCiphertext2HandlesValidityProofContext, - BatchedGroupedCiphertext2HandlesValidityProofData, - BatchedGroupedCiphertext3HandlesValidityProofContext, - BatchedGroupedCiphertext3HandlesValidityProofData, - }, - batched_range_proof::{ - batched_range_proof_u128::BatchedRangeProofU128Data, - batched_range_proof_u256::BatchedRangeProofU256Data, - batched_range_proof_u64::BatchedRangeProofU64Data, BatchedRangeProofContext, - }, - ciphertext_ciphertext_equality::{ - CiphertextCiphertextEqualityProofContext, CiphertextCiphertextEqualityProofData, - }, - ciphertext_commitment_equality::{ - CiphertextCommitmentEqualityProofContext, CiphertextCommitmentEqualityProofData, - }, - grouped_ciphertext_validity::{ - GroupedCiphertext2HandlesValidityProofContext, - GroupedCiphertext2HandlesValidityProofData, - GroupedCiphertext3HandlesValidityProofContext, - GroupedCiphertext3HandlesValidityProofData, - }, - percentage_with_cap::{PercentageWithCapProofContext, PercentageWithCapProofData}, - pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, - zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, - }, zero_ciphertext::ZeroCiphertextProofDataExt, }; @@ -93,6 +92,7 @@ pub trait ZkProofData { fn verify_proof(&self) -> Result<(), ProofVerificationError>; } +#[cfg(not(target_os = "solana"))] trait ProofContext { fn new_transcript(&self) -> Transcript; } diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs index 29fc3b2..b354f07 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/percentage_with_cap.rs @@ -7,12 +7,9 @@ //! - the `delta` and `claimed` amounts are equal use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::pedersen::PodPedersenCommitment, - proof_data::percentage_with_cap::{ - PercentageWithCapProofContext, PercentageWithCapProofData, - }, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::percentage_with_cap::{ + PercentageWithCapProofContext, PercentageWithCapProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -20,13 +17,18 @@ use { crate::{ encryption::pedersen::{PedersenCommitment, PedersenOpening}, sigma_proofs::percentage_with_cap::PercentageWithCapProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::pedersen::PodPedersenCommitment, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait PercentageWithCapProofDataExt { #[allow(clippy::too_many_arguments)] fn new( diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs index e46f3d0..d66d11b 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs @@ -6,10 +6,9 @@ //! public key. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::PodElGamalPubkey, - proof_data::pubkey_validity::{PubkeyValidityProofContext, PubkeyValidityProofData}, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::pubkey_validity::{ + PubkeyValidityProofContext, PubkeyValidityProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -17,13 +16,18 @@ use { crate::{ encryption::elgamal::ElGamalKeypair, sigma_proofs::pubkey_validity::PubkeyValidityProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::PodElGamalPubkey, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait PubkeyValidityProofDataExt { fn new(keypair: &ElGamalKeypair) -> Result where diff --git a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs index 88f2b89..a7b6605 100644 --- a/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs +++ b/zk-sdk/src/zk_elgamal_proof_program/proof_data/zero_ciphertext.rs @@ -5,10 +5,9 @@ //! generate the proof, a prover must provide the decryption key for the ciphertext. use { - crate::zk_elgamal_proof_program::proof_data::{ProofContext, ProofType, ZkProofData}, - solana_zk_sdk_pod::{ - encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, - proof_data::zero_ciphertext::{ZeroCiphertextProofContext, ZeroCiphertextProofData}, + crate::zk_elgamal_proof_program::proof_data::{ProofType, ZkProofData}, + solana_zk_sdk_pod::proof_data::zero_ciphertext::{ + ZeroCiphertextProofContext, ZeroCiphertextProofData, }, }; #[cfg(not(target_os = "solana"))] @@ -16,13 +15,18 @@ use { crate::{ encryption::elgamal::{ElGamalCiphertext, ElGamalKeypair}, sigma_proofs::zero_ciphertext::ZeroCiphertextProof, - zk_elgamal_proof_program::errors::{ProofGenerationError, ProofVerificationError}, + zk_elgamal_proof_program::{ + errors::{ProofGenerationError, ProofVerificationError}, + proof_data::ProofContext, + }, }, bytemuck::bytes_of, merlin::Transcript, + solana_zk_sdk_pod::encryption::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, std::convert::TryInto, }; +#[cfg(not(target_os = "solana"))] pub trait ZeroCiphertextProofDataExt { fn new( keypair: &ElGamalKeypair,