[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"))] #[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()
} }
} }

View File

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

View File

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

View File

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