[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"))]
|
||||
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)]
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
(fee_encryption, opening)
|
||||
(Self(grouped_ciphertext), opening)
|
||||
}
|
||||
|
||||
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_commitment(&self) -> &PedersenCommitment {
|
||||
&self.0.commitment
|
||||
}
|
||||
|
||||
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_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,
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 =
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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.withdraw_withheld_authority_handle,
|
||||
&fee_ciphertext_hi.withdraw_withheld_authority_handle,
|
||||
fee_ciphertext_lo.get_destination_handle(),
|
||||
fee_ciphertext_hi.get_destination_handle(),
|
||||
),
|
||||
(
|
||||
fee_ciphertext_lo.get_withdraw_withheld_authority_handle(),
|
||||
fee_ciphertext_hi.get_withdraw_withheld_authority_handle(),
|
||||
),
|
||||
transcript,
|
||||
)?;
|
||||
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
@ -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)]
|
||||
|
|
Loading…
Reference in New Issue