[zk-token-sdk] Define `FeeEncryption` as a wrapper around `GroupedElGamalCiphertext` (#32144)
* define `FeeEncryption` as a wrapper around `GroupedElGamalCiphertext` * define pod `FeeEncryption` as a wrapper around `GroupedElGamalCiphertext2Handles` * update proof data computation * add comments about unwraps
This commit is contained in:
parent
47ff3cecc9
commit
37f51e8376
|
@ -1,11 +1,8 @@
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
use crate::{
|
use crate::encryption::{
|
||||||
encryption::{
|
|
||||||
elgamal::{DecryptHandle, ElGamalPubkey},
|
elgamal::{DecryptHandle, ElGamalPubkey},
|
||||||
grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
|
grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
|
||||||
pedersen::{Pedersen, PedersenCommitment, PedersenOpening},
|
pedersen::{PedersenCommitment, PedersenOpening},
|
||||||
},
|
|
||||||
zk_token_elgamal::pod,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
@ -54,15 +51,10 @@ impl TransferAmountCiphertext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FeeEncryption
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[derive(Clone)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
pub struct FeeEncryption {
|
pub struct FeeEncryption(pub(crate) GroupedElGamalCiphertext<2>);
|
||||||
pub commitment: PedersenCommitment,
|
|
||||||
pub destination_handle: DecryptHandle,
|
|
||||||
pub withdraw_withheld_authority_handle: DecryptHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl FeeEncryption {
|
impl FeeEncryption {
|
||||||
|
@ -71,22 +63,29 @@ impl FeeEncryption {
|
||||||
destination_pubkey: &ElGamalPubkey,
|
destination_pubkey: &ElGamalPubkey,
|
||||||
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
|
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
|
||||||
) -> (Self, PedersenOpening) {
|
) -> (Self, PedersenOpening) {
|
||||||
let (commitment, opening) = Pedersen::new(amount);
|
let opening = PedersenOpening::new_rand();
|
||||||
let fee_encryption = Self {
|
let grouped_ciphertext = GroupedElGamal::<2>::encrypt_with(
|
||||||
commitment,
|
[destination_pubkey, withdraw_withheld_authority_pubkey],
|
||||||
destination_handle: destination_pubkey.decrypt_handle(&opening),
|
amount,
|
||||||
withdraw_withheld_authority_handle: withdraw_withheld_authority_pubkey
|
&opening,
|
||||||
.decrypt_handle(&opening),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
(fee_encryption, opening)
|
(Self(grouped_ciphertext), opening)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_pod(&self) -> pod::FeeEncryption {
|
pub fn get_commitment(&self) -> &PedersenCommitment {
|
||||||
pod::FeeEncryption {
|
&self.0.commitment
|
||||||
commitment: self.commitment.into(),
|
|
||||||
destination_handle: self.destination_handle.into(),
|
|
||||||
withdraw_withheld_authority_handle: self.withdraw_withheld_authority_handle.into(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,8 @@ impl TransferWithFeeData {
|
||||||
let pod_ciphertext_lo: pod::TransferAmountCiphertext = ciphertext_lo.into();
|
let pod_ciphertext_lo: pod::TransferAmountCiphertext = ciphertext_lo.into();
|
||||||
let pod_ciphertext_hi: pod::TransferAmountCiphertext = ciphertext_hi.into();
|
let pod_ciphertext_hi: pod::TransferAmountCiphertext = ciphertext_hi.into();
|
||||||
let pod_new_source_ciphertext: pod::ElGamalCiphertext = new_source_ciphertext.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_lo: pod::FeeEncryption = fee_ciphertext_lo.into();
|
||||||
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.to_pod();
|
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.into();
|
||||||
|
|
||||||
let context = TransferWithFeeProofContext {
|
let context = TransferWithFeeProofContext {
|
||||||
ciphertext_lo: pod_ciphertext_lo,
|
ciphertext_lo: pod_ciphertext_lo,
|
||||||
|
@ -266,17 +266,17 @@ impl TransferWithFeeData {
|
||||||
|
|
||||||
let fee_handle_lo = match role {
|
let fee_handle_lo = match role {
|
||||||
Role::Source => None,
|
Role::Source => None,
|
||||||
Role::Destination => Some(fee_ciphertext_lo.destination_handle),
|
Role::Destination => Some(fee_ciphertext_lo.get_destination_handle()),
|
||||||
Role::Auditor => None,
|
Role::Auditor => None,
|
||||||
Role::WithdrawWithheldAuthority => {
|
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 {
|
if let Some(handle) = fee_handle_lo {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: fee_ciphertext_lo.commitment,
|
commitment: *fee_ciphertext_lo.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -289,17 +289,17 @@ impl TransferWithFeeData {
|
||||||
|
|
||||||
let fee_handle_hi = match role {
|
let fee_handle_hi = match role {
|
||||||
Role::Source => None,
|
Role::Source => None,
|
||||||
Role::Destination => Some(fee_ciphertext_hi.destination_handle),
|
Role::Destination => Some(fee_ciphertext_hi.get_destination_handle()),
|
||||||
Role::Auditor => None,
|
Role::Auditor => None,
|
||||||
Role::WithdrawWithheldAuthority => {
|
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 {
|
if let Some(handle) = fee_handle_hi {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: fee_ciphertext_hi.commitment,
|
commitment: *fee_ciphertext_hi.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -467,8 +467,8 @@ impl TransferWithFeeProof {
|
||||||
let combined_fee_amount =
|
let combined_fee_amount =
|
||||||
combine_lo_hi_u64(fee_amount_lo, fee_amount_hi, TRANSFER_AMOUNT_LO_BITS);
|
combine_lo_hi_u64(fee_amount_lo, fee_amount_hi, TRANSFER_AMOUNT_LO_BITS);
|
||||||
let combined_fee_commitment = combine_lo_hi_commitments(
|
let combined_fee_commitment = combine_lo_hi_commitments(
|
||||||
&fee_ciphertext_lo.commitment,
|
fee_ciphertext_lo.get_commitment(),
|
||||||
&fee_ciphertext_hi.commitment,
|
fee_ciphertext_hi.get_commitment(),
|
||||||
TRANSFER_AMOUNT_LO_BITS,
|
TRANSFER_AMOUNT_LO_BITS,
|
||||||
);
|
);
|
||||||
let combined_fee_opening =
|
let combined_fee_opening =
|
||||||
|
@ -611,8 +611,8 @@ impl TransferWithFeeProof {
|
||||||
TRANSFER_AMOUNT_LO_BITS,
|
TRANSFER_AMOUNT_LO_BITS,
|
||||||
);
|
);
|
||||||
let combined_fee_commitment = combine_lo_hi_commitments(
|
let combined_fee_commitment = combine_lo_hi_commitments(
|
||||||
&fee_ciphertext_lo.commitment,
|
fee_ciphertext_lo.get_commitment(),
|
||||||
&fee_ciphertext_hi.commitment,
|
fee_ciphertext_hi.get_commitment(),
|
||||||
TRANSFER_AMOUNT_LO_BITS,
|
TRANSFER_AMOUNT_LO_BITS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -640,14 +640,17 @@ impl TransferWithFeeProof {
|
||||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||||
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
|
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
|
||||||
),
|
),
|
||||||
(&fee_ciphertext_lo.commitment, &fee_ciphertext_hi.commitment),
|
|
||||||
(
|
(
|
||||||
&fee_ciphertext_lo.destination_handle,
|
fee_ciphertext_lo.get_commitment(),
|
||||||
&fee_ciphertext_hi.destination_handle,
|
fee_ciphertext_hi.get_commitment(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
&fee_ciphertext_lo.withdraw_withheld_authority_handle,
|
fee_ciphertext_lo.get_destination_handle(),
|
||||||
&fee_ciphertext_hi.withdraw_withheld_authority_handle,
|
fee_ciphertext_hi.get_destination_handle(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
fee_ciphertext_lo.get_withdraw_withheld_authority_handle(),
|
||||||
|
fee_ciphertext_hi.get_withdraw_withheld_authority_handle(),
|
||||||
),
|
),
|
||||||
transcript,
|
transcript,
|
||||||
)?;
|
)?;
|
||||||
|
@ -663,8 +666,8 @@ impl TransferWithFeeProof {
|
||||||
ciphertext_hi.get_commitment(),
|
ciphertext_hi.get_commitment(),
|
||||||
&claimed_commitment,
|
&claimed_commitment,
|
||||||
&claimed_commitment_negated,
|
&claimed_commitment_negated,
|
||||||
&fee_ciphertext_lo.commitment,
|
fee_ciphertext_lo.get_commitment(),
|
||||||
&fee_ciphertext_hi.commitment,
|
fee_ciphertext_hi.get_commitment(),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
TRANSFER_SOURCE_AMOUNT_BITS, // 64
|
TRANSFER_SOURCE_AMOUNT_BITS, // 64
|
||||||
|
|
|
@ -53,9 +53,7 @@ mod target_arch {
|
||||||
crate::{
|
crate::{
|
||||||
curve25519::scalar::PodScalar,
|
curve25519::scalar::PodScalar,
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
instruction::transfer::{
|
instruction::transfer::{FeeParameters, TransferPubkeys, TransferWithFeePubkeys},
|
||||||
FeeEncryption, FeeParameters, TransferPubkeys, TransferWithFeePubkeys,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
|
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
|
||||||
std::convert::TryFrom,
|
std::convert::TryFrom,
|
||||||
|
@ -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 {
|
impl From<FeeParameters> for pod::FeeParameters {
|
||||||
fn from(parameters: FeeParameters) -> Self {
|
fn from(parameters: FeeParameters) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::zk_token_elgamal::pod::{
|
use crate::zk_token_elgamal::pod::{
|
||||||
DecryptHandle, ElGamalPubkey, GroupedElGamalCiphertext3Handles, PedersenCommitment, Pod,
|
ElGamalPubkey, GroupedElGamalCiphertext2Handles, GroupedElGamalCiphertext3Handles, Pod, PodU16,
|
||||||
PodU16, PodU64, Zeroable,
|
PodU64, Zeroable,
|
||||||
};
|
};
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
use crate::{errors::ProofError, instruction::transfer as decoded};
|
use crate::{errors::ProofError, instruction::transfer as decoded};
|
||||||
|
@ -44,10 +44,22 @@ impl TryFrom<TransferAmountCiphertext> for decoded::TransferAmountCiphertext {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FeeEncryption {
|
pub struct FeeEncryption(pub GroupedElGamalCiphertext2Handles);
|
||||||
pub commitment: PedersenCommitment,
|
|
||||||
pub destination_handle: DecryptHandle,
|
#[cfg(not(target_os = "solana"))]
|
||||||
pub withdraw_withheld_authority_handle: DecryptHandle,
|
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)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
|
Loading…
Reference in New Issue