[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:
samkim-crypto 2023-06-16 17:53:36 +09:00 committed by GitHub
parent 47ff3cecc9
commit 37f51e8376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 84 deletions

View File

@ -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()
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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)]