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

v1.16: [zk-token-sdk] Define FeeEncryption as a wrapper around GroupedElGamalCiphertext (backport of #32144) #32173

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 27 additions & 28 deletions zk-token-sdk/src/instruction/transfer/encryption.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#[cfg(not(target_os = "solana"))]
use crate::{
encryption::{
elgamal::{DecryptHandle, ElGamalPubkey},
grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
pedersen::{Pedersen, PedersenCommitment, PedersenOpening},
},
zk_token_elgamal::pod,
use crate::encryption::{
elgamal::{DecryptHandle, ElGamalPubkey},
grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
pedersen::{PedersenCommitment, PedersenOpening},
};

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -54,15 +51,10 @@ impl TransferAmountCiphertext {
}
}

// FeeEncryption
#[derive(Clone)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[repr(C)]
#[cfg(not(target_os = "solana"))]
pub struct FeeEncryption {
pub commitment: PedersenCommitment,
pub destination_handle: DecryptHandle,
pub withdraw_withheld_authority_handle: DecryptHandle,
}
pub struct FeeEncryption(pub(crate) GroupedElGamalCiphertext<2>);

#[cfg(not(target_os = "solana"))]
impl FeeEncryption {
Expand All @@ -71,22 +63,29 @@ impl FeeEncryption {
destination_pubkey: &ElGamalPubkey,
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
) -> (Self, PedersenOpening) {
let (commitment, opening) = Pedersen::new(amount);
let fee_encryption = Self {
commitment,
destination_handle: destination_pubkey.decrypt_handle(&opening),
withdraw_withheld_authority_handle: withdraw_withheld_authority_pubkey
.decrypt_handle(&opening),
};
let opening = PedersenOpening::new_rand();
let grouped_ciphertext = GroupedElGamal::<2>::encrypt_with(
[destination_pubkey, withdraw_withheld_authority_pubkey],
amount,
&opening,
);

(Self(grouped_ciphertext), opening)
}

pub fn get_commitment(&self) -> &PedersenCommitment {
&self.0.commitment
}

(fee_encryption, opening)
pub fn get_destination_handle(&self) -> &DecryptHandle {
// `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
// exactly two decryption handles.
self.0.handles.get(0).unwrap()
}

pub fn to_pod(&self) -> pod::FeeEncryption {
pod::FeeEncryption {
commitment: self.commitment.into(),
destination_handle: self.destination_handle.into(),
withdraw_withheld_authority_handle: self.withdraw_withheld_authority_handle.into(),
}
pub fn get_withdraw_withheld_authority_handle(&self) -> &DecryptHandle {
// `FeeEncryption` is a wrapper for `GroupedElGamalCiphertext<2>`, which holds
// exactly two decryption handles.
self.0.handles.get(1).unwrap()
}
}
45 changes: 24 additions & 21 deletions zk-token-sdk/src/instruction/transfer/with_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ impl TransferWithFeeData {
let pod_ciphertext_lo: pod::TransferAmountCiphertext = ciphertext_lo.into();
let pod_ciphertext_hi: pod::TransferAmountCiphertext = ciphertext_hi.into();
let pod_new_source_ciphertext: pod::ElGamalCiphertext = new_source_ciphertext.into();
let pod_fee_ciphertext_lo: pod::FeeEncryption = fee_ciphertext_lo.to_pod();
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.to_pod();
let pod_fee_ciphertext_lo: pod::FeeEncryption = fee_ciphertext_lo.into();
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.into();

let context = TransferWithFeeProofContext {
ciphertext_lo: pod_ciphertext_lo,
Expand Down Expand Up @@ -266,17 +266,17 @@ impl TransferWithFeeData {

let fee_handle_lo = match role {
Role::Source => None,
Role::Destination => Some(fee_ciphertext_lo.destination_handle),
Role::Destination => Some(fee_ciphertext_lo.get_destination_handle()),
Role::Auditor => None,
Role::WithdrawWithheldAuthority => {
Some(fee_ciphertext_lo.withdraw_withheld_authority_handle)
Some(fee_ciphertext_lo.get_withdraw_withheld_authority_handle())
}
};

if let Some(handle) = fee_handle_lo {
Ok(ElGamalCiphertext {
commitment: fee_ciphertext_lo.commitment,
handle,
commitment: *fee_ciphertext_lo.get_commitment(),
handle: *handle,
})
} else {
Err(ProofError::MissingCiphertext)
Expand All @@ -289,17 +289,17 @@ impl TransferWithFeeData {

let fee_handle_hi = match role {
Role::Source => None,
Role::Destination => Some(fee_ciphertext_hi.destination_handle),
Role::Destination => Some(fee_ciphertext_hi.get_destination_handle()),
Role::Auditor => None,
Role::WithdrawWithheldAuthority => {
Some(fee_ciphertext_hi.withdraw_withheld_authority_handle)
Some(fee_ciphertext_hi.get_withdraw_withheld_authority_handle())
}
};

if let Some(handle) = fee_handle_hi {
Ok(ElGamalCiphertext {
commitment: fee_ciphertext_hi.commitment,
handle,
commitment: *fee_ciphertext_hi.get_commitment(),
handle: *handle,
})
} else {
Err(ProofError::MissingCiphertext)
Expand Down Expand Up @@ -467,8 +467,8 @@ impl TransferWithFeeProof {
let combined_fee_amount =
combine_lo_hi_u64(fee_amount_lo, fee_amount_hi, TRANSFER_AMOUNT_LO_BITS);
let combined_fee_commitment = combine_lo_hi_commitments(
&fee_ciphertext_lo.commitment,
&fee_ciphertext_hi.commitment,
fee_ciphertext_lo.get_commitment(),
fee_ciphertext_hi.get_commitment(),
TRANSFER_AMOUNT_LO_BITS,
);
let combined_fee_opening =
Expand Down Expand Up @@ -611,8 +611,8 @@ impl TransferWithFeeProof {
TRANSFER_AMOUNT_LO_BITS,
);
let combined_fee_commitment = combine_lo_hi_commitments(
&fee_ciphertext_lo.commitment,
&fee_ciphertext_hi.commitment,
fee_ciphertext_lo.get_commitment(),
fee_ciphertext_hi.get_commitment(),
TRANSFER_AMOUNT_LO_BITS,
);

Expand Down Expand Up @@ -640,14 +640,17 @@ impl TransferWithFeeProof {
&transfer_with_fee_pubkeys.destination_pubkey,
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
),
(&fee_ciphertext_lo.commitment, &fee_ciphertext_hi.commitment),
(
&fee_ciphertext_lo.destination_handle,
&fee_ciphertext_hi.destination_handle,
fee_ciphertext_lo.get_commitment(),
fee_ciphertext_hi.get_commitment(),
),
(
fee_ciphertext_lo.get_destination_handle(),
fee_ciphertext_hi.get_destination_handle(),
),
(
&fee_ciphertext_lo.withdraw_withheld_authority_handle,
&fee_ciphertext_hi.withdraw_withheld_authority_handle,
fee_ciphertext_lo.get_withdraw_withheld_authority_handle(),
fee_ciphertext_hi.get_withdraw_withheld_authority_handle(),
),
transcript,
)?;
Expand All @@ -663,8 +666,8 @@ impl TransferWithFeeProof {
ciphertext_hi.get_commitment(),
&claimed_commitment,
&claimed_commitment_negated,
&fee_ciphertext_lo.commitment,
&fee_ciphertext_hi.commitment,
fee_ciphertext_lo.get_commitment(),
fee_ciphertext_hi.get_commitment(),
],
vec![
TRANSFER_SOURCE_AMOUNT_BITS, // 64
Expand Down
30 changes: 1 addition & 29 deletions zk-token-sdk/src/zk_token_elgamal/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ mod target_arch {
crate::{
curve25519::scalar::PodScalar,
errors::ProofError,
instruction::transfer::{
FeeEncryption, FeeParameters, TransferPubkeys, TransferWithFeePubkeys,
},
instruction::transfer::{FeeParameters, TransferPubkeys, TransferWithFeePubkeys},
},
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
std::convert::TryFrom,
Expand Down Expand Up @@ -135,32 +133,6 @@ mod target_arch {
}
}

impl From<FeeEncryption> for pod::FeeEncryption {
fn from(ciphertext: FeeEncryption) -> Self {
Self {
commitment: ciphertext.commitment.into(),
destination_handle: ciphertext.destination_handle.into(),
withdraw_withheld_authority_handle: ciphertext
.withdraw_withheld_authority_handle
.into(),
}
}
}

impl TryFrom<pod::FeeEncryption> for FeeEncryption {
type Error = ProofError;

fn try_from(pod: pod::FeeEncryption) -> Result<Self, Self::Error> {
Ok(Self {
commitment: pod.commitment.try_into()?,
destination_handle: pod.destination_handle.try_into()?,
withdraw_withheld_authority_handle: pod
.withdraw_withheld_authority_handle
.try_into()?,
})
}
}

impl From<FeeParameters> for pod::FeeParameters {
fn from(parameters: FeeParameters) -> Self {
Self {
Expand Down
24 changes: 18 additions & 6 deletions zk-token-sdk/src/zk_token_elgamal/pod/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::zk_token_elgamal::pod::{
DecryptHandle, ElGamalPubkey, GroupedElGamalCiphertext3Handles, PedersenCommitment, Pod,
PodU16, PodU64, Zeroable,
ElGamalPubkey, GroupedElGamalCiphertext2Handles, GroupedElGamalCiphertext3Handles, Pod, PodU16,
PodU64, Zeroable,
};
#[cfg(not(target_os = "solana"))]
use crate::{errors::ProofError, instruction::transfer as decoded};
Expand Down Expand Up @@ -44,10 +44,22 @@ impl TryFrom<TransferAmountCiphertext> for decoded::TransferAmountCiphertext {

#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct FeeEncryption {
pub commitment: PedersenCommitment,
pub destination_handle: DecryptHandle,
pub withdraw_withheld_authority_handle: DecryptHandle,
pub struct FeeEncryption(pub GroupedElGamalCiphertext2Handles);

#[cfg(not(target_os = "solana"))]
impl From<decoded::FeeEncryption> for FeeEncryption {
fn from(decoded_ciphertext: decoded::FeeEncryption) -> Self {
Self(decoded_ciphertext.0.into())
}
}

#[cfg(not(target_os = "solana"))]
impl TryFrom<FeeEncryption> for decoded::FeeEncryption {
type Error = ProofError;

fn try_from(pod_ciphertext: FeeEncryption) -> Result<Self, Self::Error> {
Ok(Self(pod_ciphertext.0.try_into()?))
}
}

#[derive(Clone, Copy, Pod, Zeroable)]
Expand Down