[zk-token-sdk] rename `TransferAmountEncryption` to `TransferAmountCiphertext` and define it as a wrapper around `GroupedElGamalCiphertext` (#32026)
* define `TransferAmountEncryption` as a wrapper around `GroupedElGamalCiphertext` * implement `From<GroupedElGamalCiphertext<3>>` for `GroupedElGamalCiphertext3Handles` * define pod `TransferAmountEncryption` as a wrapper around pod `GroupedElGamalCiphertext3Handles` * derive `Copy`, `Debug`, `Eq`, and `PartialEq` traits for `TransferAmountEncryption` * rename `TransferAmountEncryption` to `TransferAmountCiphertext` * clippy * fix target arch * add comment on why it is safe to unwrap
This commit is contained in:
parent
b06df6ad25
commit
c10d3d12a8
|
@ -2,48 +2,55 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
encryption::{
|
encryption::{
|
||||||
elgamal::{DecryptHandle, ElGamalPubkey},
|
elgamal::{DecryptHandle, ElGamalPubkey},
|
||||||
|
grouped_elgamal::{GroupedElGamal, GroupedElGamalCiphertext},
|
||||||
pedersen::{Pedersen, PedersenCommitment, PedersenOpening},
|
pedersen::{Pedersen, PedersenCommitment, PedersenOpening},
|
||||||
},
|
},
|
||||||
zk_token_elgamal::pod,
|
zk_token_elgamal::pod,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TransferAmountEncryption
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
#[derive(Clone)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
pub struct TransferAmountEncryption {
|
pub struct TransferAmountCiphertext(pub(crate) GroupedElGamalCiphertext<3>);
|
||||||
pub commitment: PedersenCommitment,
|
|
||||||
pub source_handle: DecryptHandle,
|
|
||||||
pub destination_handle: DecryptHandle,
|
|
||||||
pub auditor_handle: DecryptHandle,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl TransferAmountEncryption {
|
impl TransferAmountCiphertext {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
amount: u64,
|
amount: u64,
|
||||||
source_pubkey: &ElGamalPubkey,
|
source_pubkey: &ElGamalPubkey,
|
||||||
destination_pubkey: &ElGamalPubkey,
|
destination_pubkey: &ElGamalPubkey,
|
||||||
auditor_pubkey: &ElGamalPubkey,
|
auditor_pubkey: &ElGamalPubkey,
|
||||||
) -> (Self, PedersenOpening) {
|
) -> (Self, PedersenOpening) {
|
||||||
let (commitment, opening) = Pedersen::new(amount);
|
let opening = PedersenOpening::new_rand();
|
||||||
let transfer_amount_encryption = Self {
|
let grouped_ciphertext = GroupedElGamal::<3>::encrypt_with(
|
||||||
commitment,
|
[source_pubkey, destination_pubkey, auditor_pubkey],
|
||||||
source_handle: source_pubkey.decrypt_handle(&opening),
|
amount,
|
||||||
destination_handle: destination_pubkey.decrypt_handle(&opening),
|
&opening,
|
||||||
auditor_handle: auditor_pubkey.decrypt_handle(&opening),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
(transfer_amount_encryption, opening)
|
(Self(grouped_ciphertext), opening)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_pod(&self) -> pod::TransferAmountEncryption {
|
pub fn get_commitment(&self) -> &PedersenCommitment {
|
||||||
pod::TransferAmountEncryption {
|
&self.0.commitment
|
||||||
commitment: self.commitment.into(),
|
|
||||||
source_handle: self.source_handle.into(),
|
|
||||||
destination_handle: self.destination_handle.into(),
|
|
||||||
auditor_handle: self.auditor_handle.into(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_source_handle(&self) -> &DecryptHandle {
|
||||||
|
// `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which
|
||||||
|
// holds exactly three decryption handles.
|
||||||
|
self.0.handles.get(0).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_destination_handle(&self) -> &DecryptHandle {
|
||||||
|
// `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which holds
|
||||||
|
// exactly three decryption handles.
|
||||||
|
self.0.handles.get(1).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_auditor_handle(&self) -> &DecryptHandle {
|
||||||
|
// `TransferAmountCiphertext` is a wrapper for `GroupedElGamalCiphertext<3>`, which holds
|
||||||
|
// exactly three decryption handles.
|
||||||
|
self.0.handles.get(2).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use {
|
||||||
};
|
};
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
pub use {
|
pub use {
|
||||||
encryption::{FeeEncryption, TransferAmountEncryption},
|
encryption::{FeeEncryption, TransferAmountCiphertext},
|
||||||
with_fee::TransferWithFeePubkeys,
|
with_fee::TransferWithFeePubkeys,
|
||||||
without_fee::TransferPubkeys,
|
without_fee::TransferPubkeys,
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ use {
|
||||||
instruction::transfer::{
|
instruction::transfer::{
|
||||||
combine_lo_hi_ciphertexts, combine_lo_hi_commitments, combine_lo_hi_openings,
|
combine_lo_hi_ciphertexts, combine_lo_hi_commitments, combine_lo_hi_openings,
|
||||||
combine_lo_hi_u64,
|
combine_lo_hi_u64,
|
||||||
encryption::{FeeEncryption, TransferAmountEncryption},
|
encryption::{FeeEncryption, TransferAmountCiphertext},
|
||||||
split_u64, FeeParameters, Role,
|
split_u64, FeeParameters, Role,
|
||||||
},
|
},
|
||||||
range_proof::RangeProof,
|
range_proof::RangeProof,
|
||||||
|
@ -80,10 +80,10 @@ pub struct TransferWithFeeData {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransferWithFeeProofContext {
|
pub struct TransferWithFeeProofContext {
|
||||||
/// Group encryption of the low 16 bites of the transfer amount
|
/// Group encryption of the low 16 bites of the transfer amount
|
||||||
pub ciphertext_lo: pod::TransferAmountEncryption, // 128 bytes
|
pub ciphertext_lo: pod::TransferAmountCiphertext, // 128 bytes
|
||||||
|
|
||||||
/// Group encryption of the high 48 bits of the transfer amount
|
/// Group encryption of the high 48 bits of the transfer amount
|
||||||
pub ciphertext_hi: pod::TransferAmountEncryption, // 128 bytes
|
pub ciphertext_hi: pod::TransferAmountCiphertext, // 128 bytes
|
||||||
|
|
||||||
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
||||||
pub transfer_with_fee_pubkeys: pod::TransferWithFeePubkeys, // 128 bytes
|
pub transfer_with_fee_pubkeys: pod::TransferWithFeePubkeys, // 128 bytes
|
||||||
|
@ -114,13 +114,13 @@ impl TransferWithFeeData {
|
||||||
// split and encrypt transfer amount
|
// split and encrypt transfer amount
|
||||||
let (amount_lo, amount_hi) = split_u64(transfer_amount, TRANSFER_AMOUNT_LO_BITS);
|
let (amount_lo, amount_hi) = split_u64(transfer_amount, TRANSFER_AMOUNT_LO_BITS);
|
||||||
|
|
||||||
let (ciphertext_lo, opening_lo) = TransferAmountEncryption::new(
|
let (ciphertext_lo, opening_lo) = TransferAmountCiphertext::new(
|
||||||
amount_lo,
|
amount_lo,
|
||||||
&source_keypair.public,
|
&source_keypair.public,
|
||||||
destination_pubkey,
|
destination_pubkey,
|
||||||
auditor_pubkey,
|
auditor_pubkey,
|
||||||
);
|
);
|
||||||
let (ciphertext_hi, opening_hi) = TransferAmountEncryption::new(
|
let (ciphertext_hi, opening_hi) = TransferAmountCiphertext::new(
|
||||||
amount_hi,
|
amount_hi,
|
||||||
&source_keypair.public,
|
&source_keypair.public,
|
||||||
destination_pubkey,
|
destination_pubkey,
|
||||||
|
@ -133,13 +133,13 @@ impl TransferWithFeeData {
|
||||||
.ok_or(ProofError::Generation)?;
|
.ok_or(ProofError::Generation)?;
|
||||||
|
|
||||||
let transfer_amount_lo_source = ElGamalCiphertext {
|
let transfer_amount_lo_source = ElGamalCiphertext {
|
||||||
commitment: ciphertext_lo.commitment,
|
commitment: *ciphertext_lo.get_commitment(),
|
||||||
handle: ciphertext_lo.source_handle,
|
handle: *ciphertext_lo.get_source_handle(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let transfer_amount_hi_source = ElGamalCiphertext {
|
let transfer_amount_hi_source = ElGamalCiphertext {
|
||||||
commitment: ciphertext_hi.commitment,
|
commitment: *ciphertext_hi.get_commitment(),
|
||||||
handle: ciphertext_hi.source_handle,
|
handle: *ciphertext_hi.get_source_handle(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_source_ciphertext = old_source_ciphertext
|
let new_source_ciphertext = old_source_ciphertext
|
||||||
|
@ -182,8 +182,8 @@ impl TransferWithFeeData {
|
||||||
auditor_pubkey: (*auditor_pubkey).into(),
|
auditor_pubkey: (*auditor_pubkey).into(),
|
||||||
withdraw_withheld_authority_pubkey: (*withdraw_withheld_authority_pubkey).into(),
|
withdraw_withheld_authority_pubkey: (*withdraw_withheld_authority_pubkey).into(),
|
||||||
};
|
};
|
||||||
let pod_ciphertext_lo: pod::TransferAmountEncryption = ciphertext_lo.to_pod();
|
let pod_ciphertext_lo: pod::TransferAmountCiphertext = ciphertext_lo.into();
|
||||||
let pod_ciphertext_hi: pod::TransferAmountEncryption = ciphertext_hi.to_pod();
|
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.to_pod();
|
||||||
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.to_pod();
|
let pod_fee_ciphertext_hi: pod::FeeEncryption = fee_ciphertext_hi.to_pod();
|
||||||
|
@ -219,19 +219,19 @@ impl TransferWithFeeData {
|
||||||
|
|
||||||
/// Extracts the lo ciphertexts associated with a transfer-with-fee data
|
/// Extracts the lo ciphertexts associated with a transfer-with-fee data
|
||||||
fn ciphertext_lo(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
fn ciphertext_lo(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
||||||
let ciphertext_lo: TransferAmountEncryption = self.context.ciphertext_lo.try_into()?;
|
let ciphertext_lo: TransferAmountCiphertext = self.context.ciphertext_lo.try_into()?;
|
||||||
|
|
||||||
let handle_lo = match role {
|
let handle_lo = match role {
|
||||||
Role::Source => Some(ciphertext_lo.source_handle),
|
Role::Source => Some(ciphertext_lo.get_source_handle()),
|
||||||
Role::Destination => Some(ciphertext_lo.destination_handle),
|
Role::Destination => Some(ciphertext_lo.get_destination_handle()),
|
||||||
Role::Auditor => Some(ciphertext_lo.auditor_handle),
|
Role::Auditor => Some(ciphertext_lo.get_auditor_handle()),
|
||||||
Role::WithdrawWithheldAuthority => None,
|
Role::WithdrawWithheldAuthority => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(handle) = handle_lo {
|
if let Some(handle) = handle_lo {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: ciphertext_lo.commitment,
|
commitment: *ciphertext_lo.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -240,19 +240,19 @@ impl TransferWithFeeData {
|
||||||
|
|
||||||
/// Extracts the lo ciphertexts associated with a transfer-with-fee data
|
/// Extracts the lo ciphertexts associated with a transfer-with-fee data
|
||||||
fn ciphertext_hi(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
fn ciphertext_hi(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
||||||
let ciphertext_hi: TransferAmountEncryption = self.context.ciphertext_hi.try_into()?;
|
let ciphertext_hi: TransferAmountCiphertext = self.context.ciphertext_hi.try_into()?;
|
||||||
|
|
||||||
let handle_hi = match role {
|
let handle_hi = match role {
|
||||||
Role::Source => Some(ciphertext_hi.source_handle),
|
Role::Source => Some(ciphertext_hi.get_source_handle()),
|
||||||
Role::Destination => Some(ciphertext_hi.destination_handle),
|
Role::Destination => Some(ciphertext_hi.get_destination_handle()),
|
||||||
Role::Auditor => Some(ciphertext_hi.auditor_handle),
|
Role::Auditor => Some(ciphertext_hi.get_auditor_handle()),
|
||||||
Role::WithdrawWithheldAuthority => None,
|
Role::WithdrawWithheldAuthority => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(handle) = handle_hi {
|
if let Some(handle) = handle_hi {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: ciphertext_hi.commitment,
|
commitment: *ciphertext_hi.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -411,8 +411,8 @@ impl TransferWithFeeProof {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[allow(clippy::many_single_char_names)]
|
#[allow(clippy::many_single_char_names)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
transfer_amount_lo_data: (u64, &TransferAmountEncryption, &PedersenOpening),
|
transfer_amount_lo_data: (u64, &TransferAmountCiphertext, &PedersenOpening),
|
||||||
transfer_amount_hi_data: (u64, &TransferAmountEncryption, &PedersenOpening),
|
transfer_amount_hi_data: (u64, &TransferAmountCiphertext, &PedersenOpening),
|
||||||
source_keypair: &ElGamalKeypair,
|
source_keypair: &ElGamalKeypair,
|
||||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||||
(source_new_balance, new_source_ciphertext): (u64, &ElGamalCiphertext),
|
(source_new_balance, new_source_ciphertext): (u64, &ElGamalCiphertext),
|
||||||
|
@ -456,8 +456,8 @@ impl TransferWithFeeProof {
|
||||||
transcript.append_commitment(b"commitment-claimed", &pod_claimed_commitment);
|
transcript.append_commitment(b"commitment-claimed", &pod_claimed_commitment);
|
||||||
|
|
||||||
let combined_commitment = combine_lo_hi_commitments(
|
let combined_commitment = combine_lo_hi_commitments(
|
||||||
&ciphertext_lo.commitment,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.commitment,
|
ciphertext_hi.get_commitment(),
|
||||||
TRANSFER_AMOUNT_LO_BITS,
|
TRANSFER_AMOUNT_LO_BITS,
|
||||||
);
|
);
|
||||||
let combined_opening =
|
let combined_opening =
|
||||||
|
@ -549,8 +549,8 @@ impl TransferWithFeeProof {
|
||||||
|
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
&self,
|
&self,
|
||||||
ciphertext_lo: &TransferAmountEncryption,
|
ciphertext_lo: &TransferAmountCiphertext,
|
||||||
ciphertext_hi: &TransferAmountEncryption,
|
ciphertext_hi: &TransferAmountCiphertext,
|
||||||
transfer_with_fee_pubkeys: &TransferWithFeePubkeys,
|
transfer_with_fee_pubkeys: &TransferWithFeePubkeys,
|
||||||
new_spendable_ciphertext: &ElGamalCiphertext,
|
new_spendable_ciphertext: &ElGamalCiphertext,
|
||||||
// fee parameters
|
// fee parameters
|
||||||
|
@ -586,12 +586,18 @@ impl TransferWithFeeProof {
|
||||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||||
&transfer_with_fee_pubkeys.auditor_pubkey,
|
&transfer_with_fee_pubkeys.auditor_pubkey,
|
||||||
),
|
),
|
||||||
(&ciphertext_lo.commitment, &ciphertext_hi.commitment),
|
|
||||||
(
|
(
|
||||||
&ciphertext_lo.destination_handle,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.destination_handle,
|
ciphertext_hi.get_commitment(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ciphertext_lo.get_destination_handle(),
|
||||||
|
ciphertext_hi.get_destination_handle(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ciphertext_lo.get_auditor_handle(),
|
||||||
|
ciphertext_hi.get_auditor_handle(),
|
||||||
),
|
),
|
||||||
(&ciphertext_lo.auditor_handle, &ciphertext_hi.auditor_handle),
|
|
||||||
transcript,
|
transcript,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -599,8 +605,8 @@ impl TransferWithFeeProof {
|
||||||
transcript.append_commitment(b"commitment-claimed", &self.claimed_commitment);
|
transcript.append_commitment(b"commitment-claimed", &self.claimed_commitment);
|
||||||
|
|
||||||
let combined_commitment = combine_lo_hi_commitments(
|
let combined_commitment = combine_lo_hi_commitments(
|
||||||
&ciphertext_lo.commitment,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.commitment,
|
ciphertext_hi.get_commitment(),
|
||||||
TRANSFER_AMOUNT_LO_BITS,
|
TRANSFER_AMOUNT_LO_BITS,
|
||||||
);
|
);
|
||||||
let combined_fee_commitment = combine_lo_hi_commitments(
|
let combined_fee_commitment = combine_lo_hi_commitments(
|
||||||
|
@ -652,8 +658,8 @@ impl TransferWithFeeProof {
|
||||||
range_proof.verify(
|
range_proof.verify(
|
||||||
vec![
|
vec![
|
||||||
&new_source_commitment,
|
&new_source_commitment,
|
||||||
&ciphertext_lo.commitment,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.commitment,
|
ciphertext_hi.get_commitment(),
|
||||||
&claimed_commitment,
|
&claimed_commitment,
|
||||||
&claimed_commitment_negated,
|
&claimed_commitment_negated,
|
||||||
&fee_ciphertext_lo.commitment,
|
&fee_ciphertext_lo.commitment,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use {
|
||||||
},
|
},
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
instruction::transfer::{
|
instruction::transfer::{
|
||||||
combine_lo_hi_ciphertexts, encryption::TransferAmountEncryption, split_u64, Role,
|
combine_lo_hi_ciphertexts, encryption::TransferAmountCiphertext, split_u64, Role,
|
||||||
},
|
},
|
||||||
range_proof::RangeProof,
|
range_proof::RangeProof,
|
||||||
sigma_proofs::{
|
sigma_proofs::{
|
||||||
|
@ -63,10 +63,10 @@ pub struct TransferData {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransferProofContext {
|
pub struct TransferProofContext {
|
||||||
/// Group encryption of the low 16 bits of the transfer amount
|
/// Group encryption of the low 16 bits of the transfer amount
|
||||||
pub ciphertext_lo: pod::TransferAmountEncryption, // 128 bytes
|
pub ciphertext_lo: pod::TransferAmountCiphertext, // 128 bytes
|
||||||
|
|
||||||
/// Group encryption of the high 48 bits of the transfer amount
|
/// Group encryption of the high 48 bits of the transfer amount
|
||||||
pub ciphertext_hi: pod::TransferAmountEncryption, // 128 bytes
|
pub ciphertext_hi: pod::TransferAmountCiphertext, // 128 bytes
|
||||||
|
|
||||||
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
||||||
pub transfer_pubkeys: pod::TransferPubkeys, // 96 bytes
|
pub transfer_pubkeys: pod::TransferPubkeys, // 96 bytes
|
||||||
|
@ -87,14 +87,14 @@ impl TransferData {
|
||||||
// split and encrypt transfer amount
|
// split and encrypt transfer amount
|
||||||
let (amount_lo, amount_hi) = split_u64(transfer_amount, TRANSFER_AMOUNT_LO_BITS);
|
let (amount_lo, amount_hi) = split_u64(transfer_amount, TRANSFER_AMOUNT_LO_BITS);
|
||||||
|
|
||||||
let (ciphertext_lo, opening_lo) = TransferAmountEncryption::new(
|
let (ciphertext_lo, opening_lo) = TransferAmountCiphertext::new(
|
||||||
amount_lo,
|
amount_lo,
|
||||||
&source_keypair.public,
|
&source_keypair.public,
|
||||||
destination_pubkey,
|
destination_pubkey,
|
||||||
auditor_pubkey,
|
auditor_pubkey,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (ciphertext_hi, opening_hi) = TransferAmountEncryption::new(
|
let (ciphertext_hi, opening_hi) = TransferAmountCiphertext::new(
|
||||||
amount_hi,
|
amount_hi,
|
||||||
&source_keypair.public,
|
&source_keypair.public,
|
||||||
destination_pubkey,
|
destination_pubkey,
|
||||||
|
@ -107,13 +107,13 @@ impl TransferData {
|
||||||
.ok_or(ProofError::Generation)?;
|
.ok_or(ProofError::Generation)?;
|
||||||
|
|
||||||
let transfer_amount_lo_source = ElGamalCiphertext {
|
let transfer_amount_lo_source = ElGamalCiphertext {
|
||||||
commitment: ciphertext_lo.commitment,
|
commitment: *ciphertext_lo.get_commitment(),
|
||||||
handle: ciphertext_lo.source_handle,
|
handle: *ciphertext_lo.get_source_handle(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let transfer_amount_hi_source = ElGamalCiphertext {
|
let transfer_amount_hi_source = ElGamalCiphertext {
|
||||||
commitment: ciphertext_hi.commitment,
|
commitment: *ciphertext_hi.get_commitment(),
|
||||||
handle: ciphertext_hi.source_handle,
|
handle: *ciphertext_hi.get_source_handle(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_source_ciphertext = ciphertext_old_source
|
let new_source_ciphertext = ciphertext_old_source
|
||||||
|
@ -129,8 +129,8 @@ impl TransferData {
|
||||||
destination_pubkey: (*destination_pubkey).into(),
|
destination_pubkey: (*destination_pubkey).into(),
|
||||||
auditor_pubkey: (*auditor_pubkey).into(),
|
auditor_pubkey: (*auditor_pubkey).into(),
|
||||||
};
|
};
|
||||||
let pod_ciphertext_lo: pod::TransferAmountEncryption = ciphertext_lo.into();
|
let pod_ciphertext_lo: pod::TransferAmountCiphertext = ciphertext_lo.into();
|
||||||
let pod_ciphertext_hi: pod::TransferAmountEncryption = 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 context = TransferProofContext {
|
let context = TransferProofContext {
|
||||||
|
@ -156,19 +156,19 @@ impl TransferData {
|
||||||
|
|
||||||
/// Extracts the lo ciphertexts associated with a transfer data
|
/// Extracts the lo ciphertexts associated with a transfer data
|
||||||
fn ciphertext_lo(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
fn ciphertext_lo(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
||||||
let ciphertext_lo: TransferAmountEncryption = self.context.ciphertext_lo.try_into()?;
|
let ciphertext_lo: TransferAmountCiphertext = self.context.ciphertext_lo.try_into()?;
|
||||||
|
|
||||||
let handle_lo = match role {
|
let handle_lo = match role {
|
||||||
Role::Source => Some(ciphertext_lo.source_handle),
|
Role::Source => Some(ciphertext_lo.get_source_handle()),
|
||||||
Role::Destination => Some(ciphertext_lo.destination_handle),
|
Role::Destination => Some(ciphertext_lo.get_destination_handle()),
|
||||||
Role::Auditor => Some(ciphertext_lo.auditor_handle),
|
Role::Auditor => Some(ciphertext_lo.get_auditor_handle()),
|
||||||
Role::WithdrawWithheldAuthority => None,
|
Role::WithdrawWithheldAuthority => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(handle) = handle_lo {
|
if let Some(handle) = handle_lo {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: ciphertext_lo.commitment,
|
commitment: *ciphertext_lo.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -177,19 +177,19 @@ impl TransferData {
|
||||||
|
|
||||||
/// Extracts the lo ciphertexts associated with a transfer data
|
/// Extracts the lo ciphertexts associated with a transfer data
|
||||||
fn ciphertext_hi(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
fn ciphertext_hi(&self, role: Role) -> Result<ElGamalCiphertext, ProofError> {
|
||||||
let ciphertext_hi: TransferAmountEncryption = self.context.ciphertext_hi.try_into()?;
|
let ciphertext_hi: TransferAmountCiphertext = self.context.ciphertext_hi.try_into()?;
|
||||||
|
|
||||||
let handle_hi = match role {
|
let handle_hi = match role {
|
||||||
Role::Source => Some(ciphertext_hi.source_handle),
|
Role::Source => Some(ciphertext_hi.get_source_handle()),
|
||||||
Role::Destination => Some(ciphertext_hi.destination_handle),
|
Role::Destination => Some(ciphertext_hi.get_destination_handle()),
|
||||||
Role::Auditor => Some(ciphertext_hi.auditor_handle),
|
Role::Auditor => Some(ciphertext_hi.get_auditor_handle()),
|
||||||
Role::WithdrawWithheldAuthority => None,
|
Role::WithdrawWithheldAuthority => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(handle) = handle_hi {
|
if let Some(handle) = handle_hi {
|
||||||
Ok(ElGamalCiphertext {
|
Ok(ElGamalCiphertext {
|
||||||
commitment: ciphertext_hi.commitment,
|
commitment: *ciphertext_hi.get_commitment(),
|
||||||
handle,
|
handle: *handle,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(ProofError::MissingCiphertext)
|
Err(ProofError::MissingCiphertext)
|
||||||
|
@ -353,8 +353,8 @@ impl TransferProof {
|
||||||
|
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
&self,
|
&self,
|
||||||
ciphertext_lo: &TransferAmountEncryption,
|
ciphertext_lo: &TransferAmountCiphertext,
|
||||||
ciphertext_hi: &TransferAmountEncryption,
|
ciphertext_hi: &TransferAmountCiphertext,
|
||||||
transfer_pubkeys: &TransferPubkeys,
|
transfer_pubkeys: &TransferPubkeys,
|
||||||
ciphertext_new_spendable: &ElGamalCiphertext,
|
ciphertext_new_spendable: &ElGamalCiphertext,
|
||||||
transcript: &mut Transcript,
|
transcript: &mut Transcript,
|
||||||
|
@ -380,12 +380,18 @@ impl TransferProof {
|
||||||
&transfer_pubkeys.destination_pubkey,
|
&transfer_pubkeys.destination_pubkey,
|
||||||
&transfer_pubkeys.auditor_pubkey,
|
&transfer_pubkeys.auditor_pubkey,
|
||||||
),
|
),
|
||||||
(&ciphertext_lo.commitment, &ciphertext_hi.commitment),
|
|
||||||
(
|
(
|
||||||
&ciphertext_lo.destination_handle,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.destination_handle,
|
ciphertext_hi.get_commitment(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ciphertext_lo.get_destination_handle(),
|
||||||
|
ciphertext_hi.get_destination_handle(),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ciphertext_lo.get_auditor_handle(),
|
||||||
|
ciphertext_hi.get_auditor_handle(),
|
||||||
),
|
),
|
||||||
(&ciphertext_lo.auditor_handle, &ciphertext_hi.auditor_handle),
|
|
||||||
transcript,
|
transcript,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -395,8 +401,8 @@ impl TransferProof {
|
||||||
range_proof.verify(
|
range_proof.verify(
|
||||||
vec![
|
vec![
|
||||||
&new_source_commitment,
|
&new_source_commitment,
|
||||||
&ciphertext_lo.commitment,
|
ciphertext_lo.get_commitment(),
|
||||||
&ciphertext_hi.commitment,
|
ciphertext_hi.get_commitment(),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
TRANSFER_SOURCE_AMOUNT_BITS,
|
TRANSFER_SOURCE_AMOUNT_BITS,
|
||||||
|
@ -406,14 +412,14 @@ impl TransferProof {
|
||||||
transcript,
|
transcript,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
let commitment_lo_negated = &(*COMMITMENT_MAX) - &ciphertext_lo.commitment;
|
let commitment_lo_negated = &(*COMMITMENT_MAX) - ciphertext_lo.get_commitment();
|
||||||
|
|
||||||
range_proof.verify(
|
range_proof.verify(
|
||||||
vec![
|
vec![
|
||||||
&new_source_commitment,
|
&new_source_commitment,
|
||||||
&ciphertext_lo.commitment,
|
ciphertext_lo.get_commitment(),
|
||||||
&commitment_lo_negated,
|
&commitment_lo_negated,
|
||||||
&ciphertext_hi.commitment,
|
ciphertext_hi.get_commitment(),
|
||||||
],
|
],
|
||||||
vec![
|
vec![
|
||||||
TRANSFER_SOURCE_AMOUNT_BITS,
|
TRANSFER_SOURCE_AMOUNT_BITS,
|
||||||
|
|
|
@ -54,8 +54,7 @@ mod target_arch {
|
||||||
curve25519::scalar::PodScalar,
|
curve25519::scalar::PodScalar,
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
instruction::transfer::{
|
instruction::transfer::{
|
||||||
FeeEncryption, FeeParameters, TransferAmountEncryption, TransferPubkeys,
|
FeeEncryption, FeeParameters, TransferPubkeys, TransferWithFeePubkeys,
|
||||||
TransferWithFeePubkeys,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
|
curve25519_dalek::{ristretto::CompressedRistretto, scalar::Scalar},
|
||||||
|
@ -136,30 +135,6 @@ mod target_arch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TransferAmountEncryption> for pod::TransferAmountEncryption {
|
|
||||||
fn from(ciphertext: TransferAmountEncryption) -> Self {
|
|
||||||
Self {
|
|
||||||
commitment: ciphertext.commitment.into(),
|
|
||||||
source_handle: ciphertext.source_handle.into(),
|
|
||||||
destination_handle: ciphertext.destination_handle.into(),
|
|
||||||
auditor_handle: ciphertext.auditor_handle.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<pod::TransferAmountEncryption> for TransferAmountEncryption {
|
|
||||||
type Error = ProofError;
|
|
||||||
|
|
||||||
fn try_from(pod: pod::TransferAmountEncryption) -> Result<Self, Self::Error> {
|
|
||||||
Ok(Self {
|
|
||||||
commitment: pod.commitment.try_into()?,
|
|
||||||
source_handle: pod.source_handle.try_into()?,
|
|
||||||
destination_handle: pod.destination_handle.try_into()?,
|
|
||||||
auditor_handle: pod.auditor_handle.try_into()?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<FeeEncryption> for pod::FeeEncryption {
|
impl From<FeeEncryption> for pod::FeeEncryption {
|
||||||
fn from(ciphertext: FeeEncryption) -> Self {
|
fn from(ciphertext: FeeEncryption) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl Default for GroupedElGamalCiphertext3Handles {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "solana"))]
|
#[cfg(not(target_os = "solana"))]
|
||||||
impl From<GroupedElGamalCiphertext<3>> for GroupedElGamalCiphertext2Handles {
|
impl From<GroupedElGamalCiphertext<3>> for GroupedElGamalCiphertext3Handles {
|
||||||
fn from(decoded_ciphertext: GroupedElGamalCiphertext<3>) -> Self {
|
fn from(decoded_ciphertext: GroupedElGamalCiphertext<3>) -> Self {
|
||||||
Self(decoded_ciphertext.to_bytes().try_into().unwrap())
|
Self(decoded_ciphertext.to_bytes().try_into().unwrap())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use crate::zk_token_elgamal::pod::{
|
use crate::zk_token_elgamal::pod::{
|
||||||
DecryptHandle, ElGamalPubkey, PedersenCommitment, Pod, PodU16, PodU64, Zeroable,
|
DecryptHandle, ElGamalPubkey, GroupedElGamalCiphertext3Handles, PedersenCommitment, Pod,
|
||||||
|
PodU16, PodU64, Zeroable,
|
||||||
};
|
};
|
||||||
|
#[cfg(not(target_os = "solana"))]
|
||||||
|
use crate::{errors::ProofError, instruction::transfer as decoded};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -21,11 +24,22 @@ pub struct TransferWithFeePubkeys {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransferAmountEncryption {
|
pub struct TransferAmountCiphertext(pub GroupedElGamalCiphertext3Handles);
|
||||||
pub commitment: PedersenCommitment,
|
|
||||||
pub source_handle: DecryptHandle,
|
#[cfg(not(target_os = "solana"))]
|
||||||
pub destination_handle: DecryptHandle,
|
impl From<decoded::TransferAmountCiphertext> for TransferAmountCiphertext {
|
||||||
pub auditor_handle: DecryptHandle,
|
fn from(decoded_ciphertext: decoded::TransferAmountCiphertext) -> Self {
|
||||||
|
Self(decoded_ciphertext.0.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "solana"))]
|
||||||
|
impl TryFrom<TransferAmountCiphertext> for decoded::TransferAmountCiphertext {
|
||||||
|
type Error = ProofError;
|
||||||
|
|
||||||
|
fn try_from(pod_ciphertext: TransferAmountCiphertext) -> Result<Self, Self::Error> {
|
||||||
|
Ok(Self(pod_ciphertext.0.try_into()?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub use {
|
||||||
elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey},
|
elgamal::{DecryptHandle, ElGamalCiphertext, ElGamalPubkey},
|
||||||
grouped_elgamal::{GroupedElGamalCiphertext2Handles, GroupedElGamalCiphertext3Handles},
|
grouped_elgamal::{GroupedElGamalCiphertext2Handles, GroupedElGamalCiphertext3Handles},
|
||||||
instruction::{
|
instruction::{
|
||||||
FeeEncryption, FeeParameters, TransferAmountEncryption, TransferPubkeys,
|
FeeEncryption, FeeParameters, TransferAmountCiphertext, TransferPubkeys,
|
||||||
TransferWithFeePubkeys,
|
TransferWithFeePubkeys,
|
||||||
},
|
},
|
||||||
pedersen::PedersenCommitment,
|
pedersen::PedersenCommitment,
|
||||||
|
|
Loading…
Reference in New Issue