Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Commit

Permalink
update serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
samkim-crypto committed Aug 15, 2024
1 parent 120a0d3 commit 9cc5ede
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 88 deletions.
95 changes: 12 additions & 83 deletions token/program-2022/src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,6 @@ use {
serde::de::Error,
};

/// helper function to convert base64 encoded string into a bytes array
fn base64_to_bytes<const N: usize, E: Error>(v: &str) -> Result<[u8; N], E> {
let bytes = BASE64_STANDARD.decode(v).map_err(Error::custom)?;

if bytes.len() != N {
return Err(Error::custom(format!(
"Length of base64 decoded bytes is not {}",
N
)));
}

let mut array = [0; N];
array.copy_from_slice(&bytes[0..N]);
Ok(array)
}

/// helper function to ser/deser COption wrapped values
pub mod coption_fromstr {
use {
Expand Down Expand Up @@ -106,14 +90,12 @@ pub mod aeciphertext_fromstr {
de::{Error, Visitor},
Deserializer, Serializer,
},
solana_zk_token_sdk::zk_token_elgamal::pod::AeCiphertext,
std::fmt,
solana_zk_sdk::encryption::pod::auth_encryption::PodAeCiphertext,
std::{fmt, str::FromStr},
};

const AE_CIPHERTEXT_LEN: usize = 36;

/// serialize AeCiphertext values supporting Display trait
pub fn serialize<S>(x: &AeCiphertext, s: S) -> Result<S::Ok, S::Error>
pub fn serialize<S>(x: &PodAeCiphertext, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Expand All @@ -123,7 +105,7 @@ pub mod aeciphertext_fromstr {
struct AeCiphertextVisitor;

impl<'de> Visitor<'de> for AeCiphertextVisitor {
type Value = AeCiphertext;
type Value = PodAeCiphertext;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a FromStr type")
Expand All @@ -133,13 +115,12 @@ pub mod aeciphertext_fromstr {
where
E: Error,
{
let array = super::base64_to_bytes::<AE_CIPHERTEXT_LEN, E>(v)?;
Ok(AeCiphertext(array))
FromStr::from_str(v).map_err(Error::custom)
}
}

/// deserialize AeCiphertext values from str
pub fn deserialize<'de, D>(d: D) -> Result<AeCiphertext, D::Error>
pub fn deserialize<'de, D>(d: D) -> Result<PodAeCiphertext, D::Error>
where
D: Deserializer<'de>,
{
Expand All @@ -154,14 +135,12 @@ pub mod elgamalpubkey_fromstr {
de::{Error, Visitor},
Deserializer, Serializer,
},
solana_zk_token_sdk::zk_token_elgamal::pod::ElGamalPubkey,
std::fmt,
solana_zk_sdk::encryption::pod::elgamal::PodElGamalPubkey,
std::{fmt, str::FromStr},
};

const ELGAMAL_PUBKEY_LEN: usize = 32;

/// serialize ElGamalPubkey values supporting Display trait
pub fn serialize<S>(x: &ElGamalPubkey, s: S) -> Result<S::Ok, S::Error>
pub fn serialize<S>(x: &PodElGamalPubkey, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Expand All @@ -171,7 +150,7 @@ pub mod elgamalpubkey_fromstr {
struct ElGamalPubkeyVisitor;

impl<'de> Visitor<'de> for ElGamalPubkeyVisitor {
type Value = ElGamalPubkey;
type Value = PodElGamalPubkey;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a FromStr type")
Expand All @@ -181,65 +160,15 @@ pub mod elgamalpubkey_fromstr {
where
E: Error,
{
let array = super::base64_to_bytes::<ELGAMAL_PUBKEY_LEN, E>(v)?;
Ok(ElGamalPubkey(array))
FromStr::from_str(v).map_err(Error::custom)
}
}

/// deserialize ElGamalPubkey values from str
pub fn deserialize<'de, D>(d: D) -> Result<ElGamalPubkey, D::Error>
pub fn deserialize<'de, D>(d: D) -> Result<PodElGamalPubkey, D::Error>
where
D: Deserializer<'de>,
{
d.deserialize_str(ElGamalPubkeyVisitor)
}
}

/// helper to ser/deser pod::DecryptHandle values
pub mod decrypthandle_fromstr {
use {
base64::{prelude::BASE64_STANDARD, Engine},
serde::{
de::{Error, Visitor},
Deserializer, Serializer,
},
solana_zk_token_sdk::zk_token_elgamal::pod::DecryptHandle,
std::fmt,
};

const DECRYPT_HANDLE_LEN: usize = 32;

/// Serialize a decrypt handle as a base64 string
pub fn serialize<S>(x: &DecryptHandle, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
s.serialize_str(&BASE64_STANDARD.encode(x.0))
}

struct DecryptHandleVisitor;

impl<'de> Visitor<'de> for DecryptHandleVisitor {
type Value = DecryptHandle;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a FromStr type")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
let array = super::base64_to_bytes::<DECRYPT_HANDLE_LEN, E>(v)?;
Ok(DecryptHandle(array))
}
}

/// Deserialize a DecryptHandle from a base64 string
pub fn deserialize<'de, D>(d: D) -> Result<DecryptHandle, D::Error>
where
D: Deserializer<'de>,
{
d.deserialize_str(DecryptHandleVisitor)
}
}
17 changes: 12 additions & 5 deletions token/program-2022/tests/serialization.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#![cfg(feature = "serde-traits")]

use {
base64::{engine::general_purpose::STANDARD, Engine},
solana_program::program_option::COption,
solana_sdk::pubkey::Pubkey,
spl_pod::optional_keys::{OptionalNonZeroElGamalPubkey, OptionalNonZeroPubkey},
spl_token_2022::{
extension::confidential_transfer,
instruction,
solana_zk_token_sdk::zk_token_elgamal::pod::{AeCiphertext, ElGamalPubkey},
solana_zk_sdk::encryption::pod::{
auth_encryption::PodAeCiphertext, elgamal::PodElGamalPubkey,
},
},
std::str::FromStr,
};
Expand Down Expand Up @@ -51,10 +54,12 @@ fn serde_instruction_optional_nonzero_pubkeys_podbool() {
Some(Pubkey::from_str("4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM").unwrap());
let authority: OptionalNonZeroPubkey = authority_option.try_into().unwrap();

let elgamal_pubkey_pod_option: Option<ElGamalPubkey> = Some(ElGamalPubkey([
let pubkey_string = STANDARD.encode([
162, 23, 108, 36, 130, 143, 18, 219, 196, 134, 242, 145, 179, 49, 229, 193, 74, 64, 3, 158,
68, 235, 124, 88, 247, 144, 164, 254, 228, 12, 173, 85,
]));
]);
let elgamal_pubkey_pod_option = Some(FromStr::from_str(&pubkey_string).unwrap());

let auditor_elgamal_pubkey: OptionalNonZeroElGamalPubkey =
elgamal_pubkey_pod_option.try_into().unwrap();

Expand Down Expand Up @@ -105,10 +110,11 @@ fn serde_instruction_optional_nonzero_pubkeys_podbool_with_none() {

#[test]
fn serde_instruction_decryptable_balance_podu64() {
let decryptable_zero_balance = AeCiphertext([
let ciphertext_string = STANDARD.encode([
56, 22, 102, 48, 112, 106, 58, 25, 25, 244, 194, 217, 73, 137, 73, 38, 24, 26, 36, 25, 235,
234, 68, 181, 11, 82, 170, 163, 89, 205, 113, 160, 55, 16, 35, 151,
]);
let decryptable_zero_balance = FromStr::from_str(&ciphertext_string).unwrap();

let inst = confidential_transfer::instruction::ConfigureAccountInstructionData {
decryptable_zero_balance,
Expand All @@ -131,10 +137,11 @@ fn serde_instruction_decryptable_balance_podu64() {
fn serde_instruction_elgamal_pubkey() {
use spl_token_2022::extension::confidential_transfer_fee::instruction::InitializeConfidentialTransferFeeConfigData;

let withdraw_withheld_authority_elgamal_pubkey = ElGamalPubkey([
let pubkey_string = STANDARD.encode([
162, 23, 108, 36, 130, 143, 18, 219, 196, 134, 242, 145, 179, 49, 229, 193, 74, 64, 3, 158,
68, 235, 124, 88, 247, 144, 164, 254, 228, 12, 173, 85,
]);
let withdraw_withheld_authority_elgamal_pubkey = FromStr::from_str(&pubkey_string).unwrap();

let inst = InitializeConfidentialTransferFeeConfigData {
authority: OptionalNonZeroPubkey::default(),
Expand Down

0 comments on commit 9cc5ede

Please sign in to comment.