[zk-token-sdk] Refactor `zk-token-elgamal` conversion code for authenticated encryption, range proof, and sigma proof types (#31855)
* refactor convert logic for `AeCiphertext` * refactor convert logic for `RangeProof` * refactor convert logic for sigma proof types * Apply suggestions from code review Co-authored-by: Tyera <teulberg@gmail.com> --------- Co-authored-by: Tyera <teulberg@gmail.com>
This commit is contained in:
parent
66558fb5c4
commit
e4fe9335e7
|
@ -52,22 +52,11 @@ mod target_arch {
|
|||
super::pod,
|
||||
crate::{
|
||||
curve25519::scalar::PodScalar,
|
||||
encryption::auth_encryption::AeCiphertext,
|
||||
errors::{ProofError, ProofVerificationError},
|
||||
errors::ProofError,
|
||||
instruction::{
|
||||
transfer::{TransferAmountEncryption, TransferPubkeys},
|
||||
transfer_with_fee::{FeeEncryption, FeeParameters, TransferWithFeePubkeys},
|
||||
},
|
||||
range_proof::{errors::RangeProofError, RangeProof},
|
||||
sigma_proofs::{
|
||||
ciphertext_ciphertext_equality_proof::CiphertextCiphertextEqualityProof,
|
||||
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof,
|
||||
errors::*,
|
||||
fee_proof::FeeSigmaProof,
|
||||
pubkey_proof::PubkeyValidityProof,
|
||||
validity_proof::{AggregatedValidityProof, ValidityProof},
|
||||
zero_balance_proof::ZeroBalanceProof,
|
||||
},
|
||||
},
|
||||
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
|
||||
std::convert::TryFrom,
|
||||
|
@ -99,207 +88,6 @@ mod target_arch {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<AeCiphertext> for pod::AeCiphertext {
|
||||
fn from(ct: AeCiphertext) -> Self {
|
||||
Self(ct.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::AeCiphertext> for AeCiphertext {
|
||||
type Error = ProofError;
|
||||
|
||||
fn try_from(ct: pod::AeCiphertext) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&ct.0).ok_or(ProofError::CiphertextDeserialization)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CiphertextCommitmentEqualityProof> for pod::CiphertextCommitmentEqualityProof {
|
||||
fn from(proof: CiphertextCommitmentEqualityProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::CiphertextCommitmentEqualityProof> for CiphertextCommitmentEqualityProof {
|
||||
type Error = EqualityProofError;
|
||||
|
||||
fn try_from(pod: pod::CiphertextCommitmentEqualityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CiphertextCiphertextEqualityProof> for pod::CiphertextCiphertextEqualityProof {
|
||||
fn from(proof: CiphertextCiphertextEqualityProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::CiphertextCiphertextEqualityProof> for CiphertextCiphertextEqualityProof {
|
||||
type Error = EqualityProofError;
|
||||
|
||||
fn try_from(pod: pod::CiphertextCiphertextEqualityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ValidityProof> for pod::ValidityProof {
|
||||
fn from(proof: ValidityProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::ValidityProof> for ValidityProof {
|
||||
type Error = ValidityProofError;
|
||||
|
||||
fn try_from(pod: pod::ValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AggregatedValidityProof> for pod::AggregatedValidityProof {
|
||||
fn from(proof: AggregatedValidityProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::AggregatedValidityProof> for AggregatedValidityProof {
|
||||
type Error = ValidityProofError;
|
||||
|
||||
fn try_from(pod: pod::AggregatedValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZeroBalanceProof> for pod::ZeroBalanceProof {
|
||||
fn from(proof: ZeroBalanceProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::ZeroBalanceProof> for ZeroBalanceProof {
|
||||
type Error = ZeroBalanceProofError;
|
||||
|
||||
fn try_from(pod: pod::ZeroBalanceProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FeeSigmaProof> for pod::FeeSigmaProof {
|
||||
fn from(proof: FeeSigmaProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::FeeSigmaProof> for FeeSigmaProof {
|
||||
type Error = FeeSigmaProofError;
|
||||
|
||||
fn try_from(pod: pod::FeeSigmaProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PubkeyValidityProof> for pod::PubkeyValidityProof {
|
||||
fn from(proof: PubkeyValidityProof) -> Self {
|
||||
Self(proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::PubkeyValidityProof> for PubkeyValidityProof {
|
||||
type Error = PubkeyValidityProofError;
|
||||
|
||||
fn try_from(pod: pod::PubkeyValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<RangeProof> for pod::RangeProof64 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
|
||||
if proof.ipp_proof.serialized_size() != 448 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 672];
|
||||
buf[..32].copy_from_slice(proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(proof.e_blinding.as_bytes());
|
||||
buf[224..672].copy_from_slice(&proof.ipp_proof.to_bytes());
|
||||
Ok(pod::RangeProof64(buf))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::RangeProof64> for RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod: pod::RangeProof64) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<RangeProof> for pod::RangeProof128 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
|
||||
if proof.ipp_proof.serialized_size() != 512 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 736];
|
||||
buf[..32].copy_from_slice(proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(proof.e_blinding.as_bytes());
|
||||
buf[224..736].copy_from_slice(&proof.ipp_proof.to_bytes());
|
||||
Ok(pod::RangeProof128(buf))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::RangeProof128> for RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod: pod::RangeProof128) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<RangeProof> for pod::RangeProof256 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(proof: RangeProof) -> Result<Self, Self::Error> {
|
||||
if proof.ipp_proof.serialized_size() != 576 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 800];
|
||||
buf[..32].copy_from_slice(proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(proof.e_blinding.as_bytes());
|
||||
buf[224..800].copy_from_slice(&proof.ipp_proof.to_bytes());
|
||||
Ok(pod::RangeProof256(buf))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<pod::RangeProof256> for RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod: pod::RangeProof256) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransferPubkeys> for pod::TransferPubkeys {
|
||||
fn from(keys: TransferPubkeys) -> Self {
|
||||
Self {
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
//! Plain Old Data types for the AES128-GCM-SIV authenticated encryption scheme.
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
use crate::{encryption::auth_encryption as decoded, errors::ProofError};
|
||||
use {
|
||||
crate::zk_token_elgamal::pod::{Pod, Zeroable},
|
||||
base64::{prelude::BASE64_STANDARD, Engine},
|
||||
std::fmt,
|
||||
};
|
||||
|
||||
/// Serialization for AeCiphertext
|
||||
/// The `AeCiphertext` type as a `Pod`.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct AeCiphertext(pub [u8; 36]);
|
||||
|
||||
// `AeCiphertext` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
// `AeCiphertext` 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 `AeCiphertext`.
|
||||
unsafe impl Zeroable for AeCiphertext {}
|
||||
unsafe impl Pod for AeCiphertext {}
|
||||
|
||||
|
@ -31,3 +36,19 @@ impl Default for AeCiphertext {
|
|||
Self::zeroed()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<decoded::AeCiphertext> for AeCiphertext {
|
||||
fn from(decoded_ciphertext: decoded::AeCiphertext) -> Self {
|
||||
Self(decoded_ciphertext.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<AeCiphertext> for decoded::AeCiphertext {
|
||||
type Error = ProofError;
|
||||
|
||||
fn try_from(pod_ciphertext: AeCiphertext) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_ciphertext.0).ok_or(ProofError::CiphertextDeserialization)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +1,128 @@
|
|||
use crate::zk_token_elgamal::pod::{Pod, Zeroable};
|
||||
//! Plain Old Data types for range proofs.
|
||||
|
||||
/// Serialization of range proofs for 64-bit numbers (for `Withdraw` instruction)
|
||||
use crate::zk_token_elgamal::pod::{Pod, Zeroable};
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
use crate::{
|
||||
errors::ProofVerificationError,
|
||||
range_proof::{self as decoded, errors::RangeProofError},
|
||||
};
|
||||
|
||||
/// The `RangeProof` type as a `Pod` restricted to proofs on 64-bit numbers.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RangeProof64(pub [u8; 672]);
|
||||
|
||||
// `PodRangeProof64` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for RangeProof64 {}
|
||||
unsafe impl Pod for RangeProof64 {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<decoded::RangeProof> for RangeProof64 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
/// Serialization of range proofs for 128-bit numbers (for `TransferRangeProof` instruction)
|
||||
fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
|
||||
if decoded_proof.ipp_proof.serialized_size() != 448 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 672];
|
||||
buf[..32].copy_from_slice(decoded_proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(decoded_proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(decoded_proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(decoded_proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(decoded_proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(decoded_proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(decoded_proof.e_blinding.as_bytes());
|
||||
buf[224..672].copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
|
||||
Ok(RangeProof64(buf))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<RangeProof64> for decoded::RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod_proof: RangeProof64) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `RangeProof` type as a `Pod` restricted to proofs on 128-bit numbers.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RangeProof128(pub [u8; 736]);
|
||||
|
||||
// `PodRangeProof128` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for RangeProof128 {}
|
||||
unsafe impl Pod for RangeProof128 {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<decoded::RangeProof> for RangeProof128 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
/// Serialization of range proofs for 128-bit numbers (for `TransferRangeProof` instruction)
|
||||
fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
|
||||
if decoded_proof.ipp_proof.serialized_size() != 512 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 736];
|
||||
buf[..32].copy_from_slice(decoded_proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(decoded_proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(decoded_proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(decoded_proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(decoded_proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(decoded_proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(decoded_proof.e_blinding.as_bytes());
|
||||
buf[224..736].copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
|
||||
Ok(RangeProof128(buf))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<RangeProof128> for decoded::RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod_proof: RangeProof128) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `RangeProof` type as a `Pod` restricted to proofs on 256-bit numbers.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct RangeProof256(pub [u8; 800]);
|
||||
|
||||
// `PodRangeProof256` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<decoded::RangeProof> for RangeProof256 {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
|
||||
if decoded_proof.ipp_proof.serialized_size() != 576 {
|
||||
return Err(ProofVerificationError::Deserialization.into());
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 800];
|
||||
buf[..32].copy_from_slice(decoded_proof.A.as_bytes());
|
||||
buf[32..64].copy_from_slice(decoded_proof.S.as_bytes());
|
||||
buf[64..96].copy_from_slice(decoded_proof.T_1.as_bytes());
|
||||
buf[96..128].copy_from_slice(decoded_proof.T_2.as_bytes());
|
||||
buf[128..160].copy_from_slice(decoded_proof.t_x.as_bytes());
|
||||
buf[160..192].copy_from_slice(decoded_proof.t_x_blinding.as_bytes());
|
||||
buf[192..224].copy_from_slice(decoded_proof.e_blinding.as_bytes());
|
||||
buf[224..800].copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
|
||||
Ok(RangeProof256(buf))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<RangeProof256> for decoded::RangeProof {
|
||||
type Error = RangeProofError;
|
||||
|
||||
fn try_from(pod_proof: RangeProof256) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 RangeProof64 {}
|
||||
unsafe impl Pod for RangeProof64 {}
|
||||
|
||||
unsafe impl Zeroable for RangeProof128 {}
|
||||
unsafe impl Pod for RangeProof128 {}
|
||||
|
||||
unsafe impl Zeroable for RangeProof256 {}
|
||||
unsafe impl Pod for RangeProof256 {}
|
||||
|
|
|
@ -1,61 +1,181 @@
|
|||
//! Plain Old Data types for sigma proofs.
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
use crate::sigma_proofs::{
|
||||
ciphertext_ciphertext_equality_proof::CiphertextCiphertextEqualityProof as DecodedCiphertextCiphertextEqualityProof,
|
||||
ciphertext_commitment_equality_proof::CiphertextCommitmentEqualityProof as DecodedCiphertextCommitmentEqualityProof,
|
||||
errors::*,
|
||||
fee_proof::FeeSigmaProof as DecodedFeeSigmaProof,
|
||||
pubkey_proof::PubkeyValidityProof as DecodedPubkeyValidityProof,
|
||||
validity_proof::{
|
||||
AggregatedValidityProof as DecodedAggregatedValidityProof,
|
||||
ValidityProof as DecodedValidityProof,
|
||||
},
|
||||
zero_balance_proof::ZeroBalanceProof as DecodedZeroBalanceProof,
|
||||
};
|
||||
use crate::zk_token_elgamal::pod::{Pod, Zeroable};
|
||||
|
||||
/// Serialization of `CiphertextCommitmentEqualityProof`
|
||||
/// The `CiphertextCommitmentEqualityProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct CiphertextCommitmentEqualityProof(pub [u8; 192]);
|
||||
|
||||
// `CiphertextCommitmentEqualityProof` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for CiphertextCommitmentEqualityProof {}
|
||||
unsafe impl Pod for CiphertextCommitmentEqualityProof {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedCiphertextCommitmentEqualityProof> for CiphertextCommitmentEqualityProof {
|
||||
fn from(decoded_proof: DecodedCiphertextCommitmentEqualityProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of `CiphertextCiphertextEqualityProof`
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<CiphertextCommitmentEqualityProof> for DecodedCiphertextCommitmentEqualityProof {
|
||||
type Error = EqualityProofError;
|
||||
|
||||
fn try_from(pod_proof: CiphertextCommitmentEqualityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `CiphertextCiphertextEqualityProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct CiphertextCiphertextEqualityProof(pub [u8; 224]);
|
||||
|
||||
// `CiphertextCiphertextEqualityProof` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for CiphertextCiphertextEqualityProof {}
|
||||
unsafe impl Pod for CiphertextCiphertextEqualityProof {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedCiphertextCiphertextEqualityProof> for CiphertextCiphertextEqualityProof {
|
||||
fn from(decoded_proof: DecodedCiphertextCiphertextEqualityProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of validity proofs
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<CiphertextCiphertextEqualityProof> for DecodedCiphertextCiphertextEqualityProof {
|
||||
type Error = EqualityProofError;
|
||||
|
||||
fn try_from(pod_proof: CiphertextCiphertextEqualityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `ValidityProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct ValidityProof(pub [u8; 160]);
|
||||
|
||||
// `ValidityProof` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for ValidityProof {}
|
||||
unsafe impl Pod for ValidityProof {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedValidityProof> for ValidityProof {
|
||||
fn from(decoded_proof: DecodedValidityProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of aggregated validity proofs
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<ValidityProof> for DecodedValidityProof {
|
||||
type Error = ValidityProofError;
|
||||
|
||||
fn try_from(pod_proof: ValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `AggregatedValidityProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct AggregatedValidityProof(pub [u8; 160]);
|
||||
|
||||
// `AggregatedValidityProof` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for AggregatedValidityProof {}
|
||||
unsafe impl Pod for AggregatedValidityProof {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedAggregatedValidityProof> for AggregatedValidityProof {
|
||||
fn from(decoded_proof: DecodedAggregatedValidityProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of zero balance proofs
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<AggregatedValidityProof> for DecodedAggregatedValidityProof {
|
||||
type Error = ValidityProofError;
|
||||
|
||||
fn try_from(pod_proof: AggregatedValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `ZeroBalanceProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct ZeroBalanceProof(pub [u8; 96]);
|
||||
|
||||
// `ZeroBalanceProof` is a Pod and Zeroable.
|
||||
// Add the marker traits manually because `bytemuck` only adds them for some `u8` arrays
|
||||
unsafe impl Zeroable for ZeroBalanceProof {}
|
||||
unsafe impl Pod for ZeroBalanceProof {}
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedZeroBalanceProof> for ZeroBalanceProof {
|
||||
fn from(decoded_proof: DecodedZeroBalanceProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialization of fee sigma proof
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<ZeroBalanceProof> for DecodedZeroBalanceProof {
|
||||
type Error = ZeroBalanceProofError;
|
||||
|
||||
fn try_from(pod_proof: ZeroBalanceProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `FeeSigmaProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(transparent)]
|
||||
pub struct FeeSigmaProof(pub [u8; 256]);
|
||||
|
||||
/// Serialization of public-key sigma proof
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedFeeSigmaProof> for FeeSigmaProof {
|
||||
fn from(decoded_proof: DecodedFeeSigmaProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<FeeSigmaProof> for DecodedFeeSigmaProof {
|
||||
type Error = FeeSigmaProofError;
|
||||
|
||||
fn try_from(pod_proof: FeeSigmaProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// The `PubkeyValidityProof` type as a `Pod`.
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(transparent)]
|
||||
pub struct PubkeyValidityProof(pub [u8; 64]);
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl From<DecodedPubkeyValidityProof> for PubkeyValidityProof {
|
||||
fn from(decoded_proof: DecodedPubkeyValidityProof) -> Self {
|
||||
Self(decoded_proof.to_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "solana"))]
|
||||
impl TryFrom<PubkeyValidityProof> for DecodedPubkeyValidityProof {
|
||||
type Error = PubkeyValidityProofError;
|
||||
|
||||
fn try_from(pod_proof: PubkeyValidityProof) -> Result<Self, Self::Error> {
|
||||
Self::from_bytes(&pod_proof.0)
|
||||
}
|
||||
}
|
||||
|
||||
// The sigma 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 sigma proof pod types.
|
||||
unsafe impl Zeroable for CiphertextCommitmentEqualityProof {}
|
||||
unsafe impl Pod for CiphertextCommitmentEqualityProof {}
|
||||
|
||||
unsafe impl Zeroable for CiphertextCiphertextEqualityProof {}
|
||||
unsafe impl Pod for CiphertextCiphertextEqualityProof {}
|
||||
|
||||
unsafe impl Zeroable for ValidityProof {}
|
||||
unsafe impl Pod for ValidityProof {}
|
||||
|
||||
unsafe impl Zeroable for AggregatedValidityProof {}
|
||||
unsafe impl Pod for AggregatedValidityProof {}
|
||||
|
||||
unsafe impl Zeroable for ZeroBalanceProof {}
|
||||
unsafe impl Pod for ZeroBalanceProof {}
|
||||
|
|
Loading…
Reference in New Issue