diff --git a/zk-sdk/src/encryption/grouped_elgamal.rs b/zk-sdk/src/encryption/grouped_elgamal.rs index e1eee744f98540..a98f45115f8803 100644 --- a/zk-sdk/src/encryption/grouped_elgamal.rs +++ b/zk-sdk/src/encryption/grouped_elgamal.rs @@ -14,6 +14,8 @@ #[cfg(not(target_arch = "wasm32"))] use crate::encryption::{discrete_log::DiscreteLog, elgamal::ElGamalSecretKey}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ encryption::{ @@ -216,6 +218,13 @@ impl GroupedElGamalCiphertext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +pub struct GroupedElGamalCiphertext2Handles(pub(crate) GroupedElGamalCiphertext<2>); +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +pub struct GroupedElGamalCiphertext3Handles(pub(crate) GroupedElGamalCiphertext<3>); + #[cfg(test)] mod tests { use {super::*, crate::encryption::elgamal::ElGamalKeypair}; diff --git a/zk-sdk/src/encryption/pedersen.rs b/zk-sdk/src/encryption/pedersen.rs index 9f6a083e0b875c..74e00fe9122c8d 100644 --- a/zk-sdk/src/encryption/pedersen.rs +++ b/zk-sdk/src/encryption/pedersen.rs @@ -65,6 +65,7 @@ impl Pedersen { /// Pedersen opening type. /// /// Instances of Pedersen openings are zeroized on drop. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Debug, Default, Serialize, Deserialize, Zeroize)] #[zeroize(drop)] pub struct PedersenOpening(Scalar); diff --git a/zk-sdk/src/encryption/pod/grouped_elgamal.rs b/zk-sdk/src/encryption/pod/grouped_elgamal.rs index 3a6dc48cd6cd11..c3fe3a38d2f4f5 100644 --- a/zk-sdk/src/encryption/pod/grouped_elgamal.rs +++ b/zk-sdk/src/encryption/pod/grouped_elgamal.rs @@ -2,6 +2,8 @@ #[cfg(not(target_os = "solana"))] use crate::encryption::grouped_elgamal::GroupedElGamalCiphertext; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ encryption::{ @@ -69,6 +71,7 @@ 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` +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct PodGroupedElGamalCiphertext2Handles( @@ -123,6 +126,7 @@ impl TryFrom for GroupedElGamalCiphertext<2 impl_extract!(TYPE = PodGroupedElGamalCiphertext2Handles); /// The `GroupedElGamalCiphertext` type with three decryption handles as a `Pod` +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct PodGroupedElGamalCiphertext3Handles( diff --git a/zk-sdk/src/encryption/pod/pedersen.rs b/zk-sdk/src/encryption/pod/pedersen.rs index 96d2154f19abfb..5e3c92e8d46d8e 100644 --- a/zk-sdk/src/encryption/pod/pedersen.rs +++ b/zk-sdk/src/encryption/pod/pedersen.rs @@ -1,5 +1,7 @@ //! Plain Old Data type for the Pedersen commitment scheme. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{encryption::pedersen::PedersenCommitment, errors::ElGamalError}, @@ -19,6 +21,7 @@ use { const PEDERSEN_COMMITMENT_MAX_BASE64_LEN: usize = 44; /// The `PedersenCommitment` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] #[repr(transparent)] pub struct PodPedersenCommitment(pub(crate) [u8; PEDERSEN_COMMITMENT_LEN]); diff --git a/zk-sdk/src/pod.rs b/zk-sdk/src/pod.rs index d0d312b976774e..fc850358b2395b 100644 --- a/zk-sdk/src/pod.rs +++ b/zk-sdk/src/pod.rs @@ -1,5 +1,8 @@ use bytemuck_derive::{Pod, Zeroable}; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] pub struct PodU16([u8; 2]); @@ -14,6 +17,7 @@ impl From for u16 { } } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Pod, Zeroable)] #[repr(transparent)] pub struct PodU64([u8; 8]); 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 a45ffd2722b4dc..0845e01e088db1 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 @@ -13,6 +13,8 @@ use crate::encryption::{ elgamal::{DecryptHandle, ElGamalPubkey}, pedersen::{PedersenCommitment, PedersenOpening}, }; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ sigma_proofs::{ @@ -34,6 +36,7 @@ use { /// first_handle_0, second_handle_0)` and `(commitment_1, first_handle_1, /// second_handle_1)`. The proof certifies the analogous decryptable properties for each one of /// these pairs of commitment and decryption handles. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct BatchedGroupedCiphertext2HandlesValidityProof(GroupedCiphertext2HandlesValidityProof); 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 62dbf0918fd6d0..3a55b9490944fa 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 @@ -17,6 +17,8 @@ use crate::encryption::{ elgamal::{DecryptHandle, ElGamalPubkey}, pedersen::{PedersenCommitment, PedersenOpening}, }; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ sigma_proofs::{ @@ -35,6 +37,7 @@ use { const BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = UNIT_LEN * 6; /// Batched grouped ciphertext validity proof with two handles. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct BatchedGroupedCiphertext3HandlesValidityProof(GroupedCiphertext3HandlesValidityProof); diff --git a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs index 44201e0594760c..39d524593f40fd 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_ciphertext_equality.rs @@ -3,6 +3,8 @@ //! The protocol guarantees computational soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -36,6 +38,7 @@ const CIPHERTEXT_CIPHERTEXT_EQUALITY_PROOF_LEN: usize = UNIT_LEN * 7; /// The ciphertext-ciphertext equality proof. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct CiphertextCiphertextEqualityProof { diff --git a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs index 56daefffd69d27..50bfe1aed222bc 100644 --- a/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs +++ b/zk-sdk/src/sigma_proofs/ciphertext_commitment_equality.rs @@ -8,6 +8,8 @@ //! The protocol guarantees computationally soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -41,6 +43,7 @@ const CIPHERTEXT_COMMITMENT_EQUALITY_PROOF_LEN: usize = UNIT_LEN * 6; /// Equality proof. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct CiphertextCommitmentEqualityProof { 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 11f46f61d86d19..f4098fdd13348f 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 @@ -8,6 +8,8 @@ //! The protocol guarantees computational soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -41,6 +43,7 @@ const GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_PROOF_LEN: usize = UNIT_LEN * 5; /// The grouped ciphertext validity proof for 2 handles. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct GroupedCiphertext2HandlesValidityProof { 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 74c90f69e57ea1..4e62b46b683eb1 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 @@ -8,6 +8,8 @@ //! The protocol guarantees computational soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -41,6 +43,7 @@ const GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_PROOF_LEN: usize = UNIT_LEN * 6; /// The grouped ciphertext validity proof for 3 handles. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct GroupedCiphertext3HandlesValidityProof { diff --git a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs index 7803ffc92044de..82eb1aa8a11902 100644 --- a/zk-sdk/src/sigma_proofs/percentage_with_cap.rs +++ b/zk-sdk/src/sigma_proofs/percentage_with_cap.rs @@ -17,6 +17,8 @@ //! //! [`ZK Token proof program`]: https://docs.solanalabs.com/runtime/zk-token-proof +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -52,6 +54,7 @@ const PERCENTAGE_WITH_CAP_PROOF_LEN: usize = UNIT_LEN * 8; /// then the `percentage_max_proof` is properly generated and `percentage_equality_proof` is /// simulated. If the encrypted amount is smaller than the maximum cap bound, the /// `percentage_equality_proof` is properly generated and `percentage_max_proof` is simulated. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone)] pub struct PercentageWithCapProof { /// Proof that the committed amount equals the maximum cap bound diff --git a/zk-sdk/src/sigma_proofs/pod.rs b/zk-sdk/src/sigma_proofs/pod.rs index eceaf447594249..0928d66fd4e2cd 100644 --- a/zk-sdk/src/sigma_proofs/pod.rs +++ b/zk-sdk/src/sigma_proofs/pod.rs @@ -15,6 +15,8 @@ use crate::sigma_proofs::{ pubkey_validity::PubkeyValidityProof, zero_ciphertext::ZeroCiphertextProof, }; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ pod::{impl_from_bytes, impl_from_str}, @@ -26,6 +28,7 @@ use { }; /// The `CiphertextCommitmentEqualityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodCiphertextCommitmentEqualityProof( @@ -68,6 +71,7 @@ impl_from_bytes!( ); /// The `CiphertextCiphertextEqualityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodCiphertextCiphertextEqualityProof( @@ -110,6 +114,7 @@ impl_from_bytes!( ); /// The `GroupedCiphertext2HandlesValidityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodGroupedCiphertext2HandlesValidityProof( @@ -122,8 +127,8 @@ impl From for PodGroupedCiphertext2Handl Self(decoded_proof.to_bytes()) } } -#[cfg(not(target_os = "solana"))] +#[cfg(not(target_os = "solana"))] impl TryFrom for GroupedCiphertext2HandlesValidityProof { type Error = ValidityProofVerificationError; @@ -152,6 +157,7 @@ impl_from_bytes!( ); /// The `GroupedCiphertext3HandlesValidityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodGroupedCiphertext3HandlesValidityProof( @@ -194,6 +200,7 @@ impl_from_bytes!( ); /// The `BatchedGroupedCiphertext2HandlesValidityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodBatchedGroupedCiphertext2HandlesValidityProof( @@ -242,6 +249,7 @@ impl_from_bytes!( ); /// The `BatchedGroupedCiphertext3HandlesValidityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodBatchedGroupedCiphertext3HandlesValidityProof( @@ -290,6 +298,7 @@ impl_from_bytes!( ); /// The `ZeroCiphertextProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy)] #[repr(transparent)] pub struct PodZeroCiphertextProof(pub(crate) [u8; ZERO_CIPHERTEXT_PROOF_LEN]); @@ -330,6 +339,7 @@ impl_from_bytes!( ); /// The `PercentageWithCapProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable)] #[repr(transparent)] pub struct PodPercentageWithCapProof(pub(crate) [u8; PERCENTAGE_WITH_CAP_PROOF_LEN]); @@ -370,6 +380,7 @@ impl_from_bytes!( ); /// The `PubkeyValidityProof` type as a `Pod`. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, bytemuck_derive::Pod, bytemuck_derive::Zeroable)] #[repr(transparent)] pub struct PodPubkeyValidityProof(pub(crate) [u8; PUBKEY_VALIDITY_PROOF_LEN]); diff --git a/zk-sdk/src/sigma_proofs/pubkey_validity.rs b/zk-sdk/src/sigma_proofs/pubkey_validity.rs index a8af3b51196c1c..3265e6e8a8daf2 100644 --- a/zk-sdk/src/sigma_proofs/pubkey_validity.rs +++ b/zk-sdk/src/sigma_proofs/pubkey_validity.rs @@ -3,6 +3,8 @@ //! The protocol guarantees computational soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -35,6 +37,7 @@ const PUBKEY_VALIDITY_PROOF_LEN: usize = UNIT_LEN * 2; /// Public-key proof. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct PubkeyValidityProof { diff --git a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs index 4b6cf95f6f463a..00e79cfcd1e2d5 100644 --- a/zk-sdk/src/sigma_proofs/zero_ciphertext.rs +++ b/zk-sdk/src/sigma_proofs/zero_ciphertext.rs @@ -3,6 +3,8 @@ //! The protocol guarantees computationally soundness (by the hardness of discrete log) and perfect //! zero-knowledge in the random oracle model. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -36,6 +38,7 @@ const ZERO_CIPHERTEXT_PROOF_LEN: usize = UNIT_LEN * 3; /// Zero-ciphertext proof. /// /// Contains all the elliptic curve and scalar components that make up the sigma protocol. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[allow(non_snake_case)] #[derive(Clone)] pub struct ZeroCiphertextProof { 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 bd6e980962b1df..8e882ba2162a28 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,10 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. +#[cfg(target_arch = "wasm32")] +use { + crate::encryption::grouped_elgamal::GroupedElGamalCiphertext2Handles, wasm_bindgen::prelude::*, +}; use { crate::{ encryption::pod::{ @@ -34,6 +38,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct BatchedGroupedCiphertext2HandlesValidityProofData { @@ -42,6 +47,7 @@ pub struct BatchedGroupedCiphertext2HandlesValidityProofData { pub proof: PodBatchedGroupedCiphertext2HandlesValidityProof, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct BatchedGroupedCiphertext2HandlesValidityProofContext { @@ -160,6 +166,39 @@ impl BatchedGroupedCiphertext2HandlesValidityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl BatchedGroupedCiphertext2HandlesValidityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + grouped_ciphertext_lo: &GroupedElGamalCiphertext2Handles, + grouped_ciphertext_hi: &GroupedElGamalCiphertext2Handles, + amount_lo: u64, + amount_hi: u64, + opening_lo: &PedersenOpening, + opening_hi: &PedersenOpening, + ) -> Result { + Self::new( + first_pubkey, + second_pubkey, + &grouped_ciphertext_lo.0, + &grouped_ciphertext_hi.0, + amount_lo, + amount_hi, + opening_lo, + opening_hi, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use { 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 7423a5427733aa..bc64a9bc290b33 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,10 @@ //! grouped-ciphertext validity proof is shorter and more efficient than two individual //! grouped-ciphertext validity proofs. +#[cfg(target_arch = "wasm32")] +use { + crate::encryption::grouped_elgamal::GroupedElGamalCiphertext3Handles, wasm_bindgen::prelude::*, +}; use { crate::{ encryption::pod::{ @@ -34,6 +38,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct BatchedGroupedCiphertext3HandlesValidityProofData { @@ -42,6 +47,7 @@ pub struct BatchedGroupedCiphertext3HandlesValidityProofData { pub proof: PodBatchedGroupedCiphertext3HandlesValidityProof, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct BatchedGroupedCiphertext3HandlesValidityProofContext { @@ -173,6 +179,41 @@ impl BatchedGroupedCiphertext3HandlesValidityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl BatchedGroupedCiphertext3HandlesValidityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + third_pubkey: &ElGamalPubkey, + grouped_ciphertext_lo: &GroupedElGamalCiphertext3Handles, + grouped_ciphertext_hi: &GroupedElGamalCiphertext3Handles, + amount_lo: u64, + amount_hi: u64, + opening_lo: &PedersenOpening, + opening_hi: &PedersenOpening, + ) -> Result { + Self::new( + first_pubkey, + second_pubkey, + third_pubkey, + &grouped_ciphertext_lo.0, + &grouped_ciphertext_hi.0, + amount_lo, + amount_hi, + opening_lo, + opening_hi, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use { 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 21437bdba7b2b3..fa4a51767c1449 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,8 @@ //! the proof, a prover must provide the decryption key for the first ciphertext and the randomness //! used to generate the second ciphertext. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ encryption::pod::elgamal::{PodElGamalCiphertext, PodElGamalPubkey}, @@ -33,6 +35,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct CiphertextCiphertextEqualityProofData { @@ -42,6 +45,7 @@ pub struct CiphertextCiphertextEqualityProofData { } /// The context data needed to verify a ciphertext-ciphertext equality proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct CiphertextCiphertextEqualityProofContext { @@ -138,6 +142,35 @@ impl CiphertextCiphertextEqualityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl CiphertextCiphertextEqualityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + first_keypair: &ElGamalKeypair, + second_pubkey: &ElGamalPubkey, + first_ciphertext: &ElGamalCiphertext, + second_ciphertext: &ElGamalCiphertext, + second_opening: &PedersenOpening, + amount: u64, + ) -> Result { + Self::new( + first_keypair, + second_pubkey, + first_ciphertext, + second_ciphertext, + second_opening, + amount, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use super::*; 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 bb093436b66f0a..7d5c263bfd0cbf 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,8 @@ //! 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. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; use { crate::{ encryption::pod::{ @@ -35,6 +37,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct CiphertextCommitmentEqualityProofData { @@ -43,6 +46,7 @@ pub struct CiphertextCommitmentEqualityProofData { } /// The context data needed to verify a ciphertext-commitment equality proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct CiphertextCommitmentEqualityProofContext { @@ -121,6 +125,27 @@ impl CiphertextCommitmentEqualityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl CiphertextCommitmentEqualityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + keypair: &ElGamalKeypair, + ciphertext: &ElGamalCiphertext, + commitment: &PedersenCommitment, + opening: &PedersenOpening, + amount: u64, + ) -> Result { + Self::new(keypair, ciphertext, commitment, opening, amount) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use { 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 5c35b1b131729a..76aefe9b1a35d3 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,10 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. +#[cfg(target_arch = "wasm32")] +use { + crate::encryption::grouped_elgamal::GroupedElGamalCiphertext2Handles, wasm_bindgen::prelude::*, +}; use { crate::{ encryption::pod::{ @@ -34,6 +38,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct GroupedCiphertext2HandlesValidityProofData { @@ -42,6 +47,7 @@ pub struct GroupedCiphertext2HandlesValidityProofData { pub proof: PodGroupedCiphertext2HandlesValidityProof, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct GroupedCiphertext2HandlesValidityProofContext { @@ -135,6 +141,33 @@ impl GroupedCiphertext2HandlesValidityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl GroupedCiphertext2HandlesValidityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + grouped_ciphertext: &GroupedElGamalCiphertext2Handles, + amount: u64, + opening: &PedersenOpening, + ) -> Result { + Self::new( + first_pubkey, + second_pubkey, + &grouped_ciphertext.0, + amount, + opening, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use { 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 5e8852f8584ca1..e2b2ed060aa0e8 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,10 @@ //! decryption handles. To generate the proof, a prover must provide the Pedersen opening //! associated with the grouped ciphertext's commitment. +#[cfg(target_arch = "wasm32")] +use { + crate::encryption::grouped_elgamal::GroupedElGamalCiphertext3Handles, wasm_bindgen::prelude::*, +}; use { crate::{ encryption::pod::{ @@ -34,6 +38,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct GroupedCiphertext3HandlesValidityProofData { @@ -42,6 +47,7 @@ pub struct GroupedCiphertext3HandlesValidityProofData { pub proof: PodGroupedCiphertext3HandlesValidityProof, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct GroupedCiphertext3HandlesValidityProofContext { @@ -146,6 +152,35 @@ impl GroupedCiphertext3HandlesValidityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl GroupedCiphertext3HandlesValidityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + first_pubkey: &ElGamalPubkey, + second_pubkey: &ElGamalPubkey, + third_pubkey: &ElGamalPubkey, + grouped_ciphertext: &GroupedElGamalCiphertext3Handles, + amount: u64, + opening: &PedersenOpening, + ) -> Result { + Self::new( + first_pubkey, + second_pubkey, + third_pubkey, + &grouped_ciphertext.0, + amount, + opening, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use { 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 6154f1ae43b0c0..fa8b0bb2af38df 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,8 @@ //! - the `percentage` amount is equal to a constant (referred to as the `max_value`) //! - the `delta` and `claimed` amounts are equal +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -32,6 +34,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct PercentageWithCapProofData { @@ -46,6 +49,7 @@ pub struct PercentageWithCapProofData { /// computed. /// /// [`ZK ElGamal proof`]: https://docs.solanalabs.com/runtime/zk-token-proof +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct PercentageWithCapProofContext { @@ -151,6 +155,41 @@ impl PercentageWithCapProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl PercentageWithCapProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + 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 { + Self::new( + percentage_commitment, + percentage_opening, + percentage_amount, + delta_commitment, + delta_opening, + delta_amount, + claimed_commitment, + claimed_opening, + max_value, + ) + .map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use {super::*, crate::encryption::pedersen::Pedersen, curve25519_dalek::scalar::Scalar}; 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 8b8ceb9c45be87..02461a3cdf3117 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,8 @@ //! corresponding secret key). To generate the proof, a prover must provide the secret key for the //! public key. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -30,6 +32,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct PubkeyValidityProofData { @@ -41,6 +44,7 @@ pub struct PubkeyValidityProofData { } /// The context data needed to verify a pubkey validity proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct PubkeyValidityProofContext { @@ -88,6 +92,20 @@ impl PubkeyValidityProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl PubkeyValidityProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data(keypair: &ElGamalKeypair) -> Result { + Self::new(keypair).map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use super::*; 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 a6c225074974a3..5ceed4d1ba7047 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,8 @@ //! 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. +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; #[cfg(not(target_os = "solana"))] use { crate::{ @@ -28,6 +30,7 @@ use { /// /// It includes the cryptographic proof as well as the context data information needed to verify /// the proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct ZeroCiphertextProofData { @@ -39,6 +42,7 @@ pub struct ZeroCiphertextProofData { } /// The context data needed to verify a zero-ciphertext proof. +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] #[derive(Clone, Copy, Pod, Zeroable)] #[repr(C)] pub struct ZeroCiphertextProofContext { @@ -102,6 +106,23 @@ impl ZeroCiphertextProofContext { } } +#[cfg(target_arch = "wasm32")] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl ZeroCiphertextProofData { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = generateProofData))] + pub fn generate_proof_data( + keypair: &ElGamalKeypair, + ciphertext: &ElGamalCiphertext, + ) -> Result { + Self::new(keypair, ciphertext).map_err(|e| e.to_string().into()) + } + + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toBytes))] + pub fn to_bytes(&self) -> Box<[u8]> { + bytes_of(self).into() + } +} + #[cfg(test)] mod test { use super::*;