diff --git a/zk-sdk/src/encryption/mod.rs b/zk-sdk/src/encryption/mod.rs index f0748d70fe6287..28a9ae6bf7fded 100644 --- a/zk-sdk/src/encryption/mod.rs +++ b/zk-sdk/src/encryption/mod.rs @@ -26,8 +26,6 @@ pub mod grouped_elgamal; #[cfg(not(target_os = "solana"))] pub mod pedersen; pub mod pod; -#[cfg(all(not(target_os = "solana"), target_arch = "wasm32"))] -pub mod wasm; /// Byte length of an authenticated encryption secret key pub const AE_KEY_LEN: usize = 16; diff --git a/zk-sdk/src/encryption/pod/elgamal.rs b/zk-sdk/src/encryption/pod/elgamal.rs index 6b30f27a127e3a..1dac45378b588c 100644 --- a/zk-sdk/src/encryption/pod/elgamal.rs +++ b/zk-sdk/src/encryption/pod/elgamal.rs @@ -17,6 +17,11 @@ use { bytemuck::Zeroable, std::fmt, }; +#[cfg(target_arch = "wasm32")] +use { + js_sys::{Array, Uint8Array}, + wasm_bindgen::prelude::*, +}; /// Maximum length of a base64 encoded ElGamal public key const ELGAMAL_PUBKEY_MAX_BASE64_LEN: usize = 44; @@ -80,8 +85,77 @@ impl TryFrom for ElGamalCiphertext { /// The `ElGamalPubkey` type as a `Pod`. #[derive(Clone, Copy, Default, bytemuck_derive::Pod, bytemuck_derive::Zeroable, PartialEq, Eq)] #[repr(transparent)] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub struct PodElGamalPubkey(pub(crate) [u8; ELGAMAL_PUBKEY_LEN]); +#[cfg(target_arch = "wasm32")] +#[allow(non_snake_case)] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl PodElGamalPubkey { + /// Create a new `PodElGamalPubkey` object + /// + /// * `value` - optional public key as a base64 encoded string, `Uint8Array`, `[number]` + #[wasm_bindgen(constructor)] + pub fn constructor(value: JsValue) -> Result { + if let Some(base64_str) = value.as_string() { + base64_str + .parse::() + .map_err(|e| e.to_string().into()) + } else if let Some(uint8_array) = value.dyn_ref::() { + bytemuck::try_from_bytes(&uint8_array.to_vec()) + .map_err(|err| JsValue::from(format!("Invalid Uint8Array ElGamalPubkey: {err:?}"))) + .map(|pubkey| *pubkey) + } else if let Some(array) = value.dyn_ref::() { + let mut bytes = vec![]; + let iterator = js_sys::try_iter(&array.values())?.expect("array to be iterable"); + for x in iterator { + let x = x?; + + if let Some(n) = x.as_f64() { + if (0. ..=255.).contains(&n) { + bytes.push(n as u8); + continue; + } + } + return Err(format!("Invalid array argument: {:?}", x).into()); + } + + bytemuck::try_from_bytes(&bytes) + .map_err(|err| JsValue::from(format!("Invalid Array pubkey: {err:?}"))) + .map(|pubkey| *pubkey) + } else if value.is_undefined() { + Ok(PodElGamalPubkey::default()) + } else { + Err("Unsupported argument".into()) + } + } + + /// Return the base64 string representation of the public key + pub fn toString(&self) -> String { + self.to_string() + } + + /// Checks if two `ElGamalPubkey`s are equal + pub fn equals(&self, other: &PodElGamalPubkey) -> bool { + self == other + } + + /// Return the `Uint8Array` representation of the public key + pub fn toBytes(&self) -> Box<[u8]> { + self.0.into() + } + + pub fn compressed(decoded: &ElGamalPubkey) -> PodElGamalPubkey { + (*decoded).into() + } + + pub fn decompressed(&self) -> Result { + (*self) + .try_into() + .map_err(|err| JsValue::from(format!("Invalid ElGamalPubkey: {err:?}"))) + } +} + impl fmt::Debug for PodElGamalPubkey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self.0) diff --git a/zk-sdk/src/encryption/wasm/elgamal.rs b/zk-sdk/src/encryption/wasm/elgamal.rs deleted file mode 100644 index 71064125ef7beb..00000000000000 --- a/zk-sdk/src/encryption/wasm/elgamal.rs +++ /dev/null @@ -1,82 +0,0 @@ -use { - crate::{ - encryption::{elgamal::ElGamalPubkey, pod::elgamal::PodElGamalPubkey}, - wasm::display_to_jsvalue, - }, - bytemuck::{Pod, Zeroable}, - js_sys::{Array, Uint8Array}, - wasm_bindgen::{prelude::*, JsCast}, -}; - -#[wasm_bindgen] -#[derive(Clone, Copy, Default, Pod, Zeroable, PartialEq, Eq)] -#[repr(transparent)] -pub struct CompressedElGamalPubkey(PodElGamalPubkey); - -#[allow(non_snake_case)] -#[wasm_bindgen] -impl CompressedElGamalPubkey { - /// Create a new `PodElGamalPubkey` object - /// - /// * `value` - optional public key as a base64 encoded string, `Uint8Array`, `[number]` - #[wasm_bindgen(constructor)] - pub fn constructor(value: JsValue) -> Result { - if let Some(base64_str) = value.as_string() { - base64_str - .parse::() - .map_err(display_to_jsvalue) - .map(CompressedElGamalPubkey) - } else if let Some(uint8_array) = value.dyn_ref::() { - bytemuck::try_from_bytes(&uint8_array.to_vec()) - .map_err(|err| JsValue::from(format!("Invalid Uint8Array ElGamalPubkey: {err:?}"))) - .map(|pubkey| CompressedElGamalPubkey(*pubkey)) - } else if let Some(array) = value.dyn_ref::() { - let mut bytes = vec![]; - let iterator = js_sys::try_iter(&array.values())?.expect("array to be iterable"); - for x in iterator { - let x = x?; - - if let Some(n) = x.as_f64() { - if (0. ..=255.).contains(&n) { - bytes.push(n as u8); - continue; - } - } - return Err(format!("Invalid array argument: {:?}", x).into()); - } - - bytemuck::try_from_bytes(&bytes) - .map_err(|err| JsValue::from(format!("Invalid Array pubkey: {err:?}"))) - .map(|pubkey| CompressedElGamalPubkey(*pubkey)) - } else if value.is_undefined() { - Ok(Self(PodElGamalPubkey::default())) - } else { - Err("Unsupported argument".into()) - } - } - - /// Return the base64 string representation of the public key - pub fn toString(&self) -> String { - self.0.to_string() - } - - /// Checks if two `ElGamalPubkey`s are equal - pub fn equals(&self, other: &CompressedElGamalPubkey) -> bool { - self == other - } - - /// Return the `Uint8Array` representation of the public key - pub fn toBytes(&self) -> Box<[u8]> { - self.0 .0.into() - } - - pub fn compressed(decoded: &ElGamalPubkey) -> Self { - Self((*decoded).into()) - } - - pub fn decompressed(&self) -> Result { - self.0 - .try_into() - .map_err(|err| JsValue::from(format!("Invalid ElGamalPubkey: {err:?}"))) - } -} diff --git a/zk-sdk/src/encryption/wasm/mod.rs b/zk-sdk/src/encryption/wasm/mod.rs deleted file mode 100644 index 2ebf262efb4b8b..00000000000000 --- a/zk-sdk/src/encryption/wasm/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod elgamal; diff --git a/zk-sdk/src/lib.rs b/zk-sdk/src/lib.rs index aeada0328108e1..8d7388475f2f36 100644 --- a/zk-sdk/src/lib.rs +++ b/zk-sdk/src/lib.rs @@ -25,8 +25,6 @@ pub mod pod; mod range_proof; mod sigma_proofs; mod transcript; -#[cfg(all(not(target_os = "solana"), target_arch = "wasm32"))] -pub mod wasm; #[cfg(not(target_arch = "wasm32"))] pub mod zk_elgamal_proof_program; diff --git a/zk-sdk/src/wasm.rs b/zk-sdk/src/wasm.rs deleted file mode 100644 index 33f61a4daaa7e8..00000000000000 --- a/zk-sdk/src/wasm.rs +++ /dev/null @@ -1,5 +0,0 @@ -use wasm_bindgen::prelude::*; - -pub fn display_to_jsvalue(display: T) -> JsValue { - display.to_string().into() -}