zk-token-sdk: change variable names to use suffix rather than prefix (#23474)
* zk-token-sdk: change variable names to use suffix rather than prefix for type * zk-token-sdk: cargo fmt
This commit is contained in:
parent
f2fa49a771
commit
8d53ea81e9
|
@ -37,25 +37,25 @@ const TRANSFER_AMOUNT_HI_BIT_LENGTH: usize = 32;
|
|||
#[cfg(not(target_arch = "bpf"))]
|
||||
pub struct TransferAmountEncryption {
|
||||
pub commitment: PedersenCommitment,
|
||||
pub handle_source: DecryptHandle,
|
||||
pub handle_dest: DecryptHandle,
|
||||
pub handle_auditor: DecryptHandle,
|
||||
pub source_handle: DecryptHandle,
|
||||
pub destination_handle: DecryptHandle,
|
||||
pub auditor_handle: DecryptHandle,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
impl TransferAmountEncryption {
|
||||
pub fn new(
|
||||
amount: u32,
|
||||
pubkey_source: &ElGamalPubkey,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
pubkey_auditor: &ElGamalPubkey,
|
||||
source_pubkey: &ElGamalPubkey,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
auditor_pubkey: &ElGamalPubkey,
|
||||
) -> (Self, PedersenOpening) {
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
let transfer_amount_encryption = Self {
|
||||
commitment,
|
||||
handle_source: pubkey_source.decrypt_handle(&opening),
|
||||
handle_dest: pubkey_dest.decrypt_handle(&opening),
|
||||
handle_auditor: pubkey_auditor.decrypt_handle(&opening),
|
||||
source_handle: source_pubkey.decrypt_handle(&opening),
|
||||
destination_handle: destination_pubkey.decrypt_handle(&opening),
|
||||
auditor_handle: auditor_pubkey.decrypt_handle(&opening),
|
||||
};
|
||||
|
||||
(transfer_amount_encryption, opening)
|
||||
|
@ -64,9 +64,9 @@ impl TransferAmountEncryption {
|
|||
pub fn to_pod(&self) -> pod::TransferAmountEncryption {
|
||||
pod::TransferAmountEncryption {
|
||||
commitment: self.commitment.into(),
|
||||
handle_source: self.handle_source.into(),
|
||||
handle_dest: self.handle_dest.into(),
|
||||
handle_auditor: self.handle_auditor.into(),
|
||||
source_handle: self.source_handle.into(),
|
||||
destination_handle: self.destination_handle.into(),
|
||||
auditor_handle: self.auditor_handle.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ pub struct TransferData {
|
|||
pub transfer_pubkeys: pod::TransferPubkeys,
|
||||
|
||||
/// The final spendable ciphertext after the transfer
|
||||
pub ciphertext_new_source: pod::ElGamalCiphertext,
|
||||
pub new_source_ciphertext: pod::ElGamalCiphertext,
|
||||
|
||||
/// Zero-knowledge proofs for Transfer
|
||||
pub proof: TransferProof,
|
||||
|
@ -96,23 +96,23 @@ impl TransferData {
|
|||
pub fn new(
|
||||
transfer_amount: u64,
|
||||
(spendable_balance, ciphertext_old_source): (u64, &ElGamalCiphertext),
|
||||
keypair_source: &ElGamalKeypair,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
source_keypair: &ElGamalKeypair,
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
) -> Result<Self, ProofError> {
|
||||
// split and encrypt transfer amount
|
||||
let (amount_lo, amount_hi) = split_u64_into_u32(transfer_amount);
|
||||
|
||||
let (ciphertext_lo, opening_lo) = TransferAmountEncryption::new(
|
||||
amount_lo,
|
||||
&keypair_source.public,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
&source_keypair.public,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
);
|
||||
let (ciphertext_hi, opening_hi) = TransferAmountEncryption::new(
|
||||
amount_hi,
|
||||
&keypair_source.public,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
&source_keypair.public,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
);
|
||||
|
||||
// subtract transfer amount from the spendable ciphertext
|
||||
|
@ -122,41 +122,41 @@ impl TransferData {
|
|||
|
||||
let transfer_amount_lo_source = ElGamalCiphertext {
|
||||
commitment: ciphertext_lo.commitment,
|
||||
handle: ciphertext_lo.handle_source,
|
||||
handle: ciphertext_lo.source_handle,
|
||||
};
|
||||
|
||||
let transfer_amount_hi_source = ElGamalCiphertext {
|
||||
commitment: ciphertext_hi.commitment,
|
||||
handle: ciphertext_hi.handle_source,
|
||||
handle: ciphertext_hi.source_handle,
|
||||
};
|
||||
|
||||
let ciphertext_new_source = ciphertext_old_source
|
||||
let new_source_ciphertext = ciphertext_old_source
|
||||
- combine_u32_ciphertexts(&transfer_amount_lo_source, &transfer_amount_hi_source);
|
||||
|
||||
// generate transcript and append all public inputs
|
||||
let pod_transfer_pubkeys = pod::TransferPubkeys {
|
||||
pubkey_source: keypair_source.public.into(),
|
||||
pubkey_dest: (*pubkey_dest).into(),
|
||||
pubkey_auditor: (*pubkey_auditor).into(),
|
||||
source_pubkey: source_keypair.public.into(),
|
||||
destination_pubkey: (*destination_pubkey).into(),
|
||||
auditor_pubkey: (*auditor_pubkey).into(),
|
||||
};
|
||||
let pod_ciphertext_lo: pod::TransferAmountEncryption = ciphertext_lo.into();
|
||||
let pod_ciphertext_hi: pod::TransferAmountEncryption = ciphertext_hi.into();
|
||||
let pod_ciphertext_new_source: pod::ElGamalCiphertext = ciphertext_new_source.into();
|
||||
let pod_new_source_ciphertext: pod::ElGamalCiphertext = new_source_ciphertext.into();
|
||||
|
||||
let mut transcript = TransferProof::transcript_new(
|
||||
&pod_transfer_pubkeys,
|
||||
&pod_ciphertext_lo,
|
||||
&pod_ciphertext_hi,
|
||||
&pod_ciphertext_new_source,
|
||||
&pod_new_source_ciphertext,
|
||||
);
|
||||
|
||||
let proof = TransferProof::new(
|
||||
(amount_lo, amount_hi),
|
||||
keypair_source,
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
source_keypair,
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
&opening_lo,
|
||||
&opening_hi,
|
||||
(new_spendable_balance, &ciphertext_new_source),
|
||||
(new_spendable_balance, &new_source_ciphertext),
|
||||
&mut transcript,
|
||||
);
|
||||
|
||||
|
@ -164,7 +164,7 @@ impl TransferData {
|
|||
ciphertext_lo: pod_ciphertext_lo,
|
||||
ciphertext_hi: pod_ciphertext_hi,
|
||||
transfer_pubkeys: pod_transfer_pubkeys,
|
||||
ciphertext_new_source: pod_ciphertext_new_source,
|
||||
new_source_ciphertext: pod_new_source_ciphertext,
|
||||
proof,
|
||||
})
|
||||
}
|
||||
|
@ -174,9 +174,9 @@ impl TransferData {
|
|||
let ciphertext_lo: TransferAmountEncryption = self.ciphertext_lo.try_into()?;
|
||||
|
||||
let handle_lo = match role {
|
||||
Role::Source => ciphertext_lo.handle_source,
|
||||
Role::Dest => ciphertext_lo.handle_dest,
|
||||
Role::Auditor => ciphertext_lo.handle_auditor,
|
||||
Role::Source => ciphertext_lo.source_handle,
|
||||
Role::Dest => ciphertext_lo.destination_handle,
|
||||
Role::Auditor => ciphertext_lo.auditor_handle,
|
||||
};
|
||||
|
||||
Ok(ElGamalCiphertext {
|
||||
|
@ -190,9 +190,9 @@ impl TransferData {
|
|||
let ciphertext_hi: TransferAmountEncryption = self.ciphertext_hi.try_into()?;
|
||||
|
||||
let handle_hi = match role {
|
||||
Role::Source => ciphertext_hi.handle_source,
|
||||
Role::Dest => ciphertext_hi.handle_dest,
|
||||
Role::Auditor => ciphertext_hi.handle_auditor,
|
||||
Role::Source => ciphertext_hi.source_handle,
|
||||
Role::Dest => ciphertext_hi.destination_handle,
|
||||
Role::Auditor => ciphertext_hi.auditor_handle,
|
||||
};
|
||||
|
||||
Ok(ElGamalCiphertext {
|
||||
|
@ -230,13 +230,13 @@ impl Verifiable for TransferData {
|
|||
&self.transfer_pubkeys,
|
||||
&self.ciphertext_lo,
|
||||
&self.ciphertext_hi,
|
||||
&self.ciphertext_new_source,
|
||||
&self.new_source_ciphertext,
|
||||
);
|
||||
|
||||
let ciphertext_lo = self.ciphertext_lo.try_into()?;
|
||||
let ciphertext_hi = self.ciphertext_hi.try_into()?;
|
||||
let transfer_pubkeys = self.transfer_pubkeys.try_into()?;
|
||||
let new_spendable_ciphertext = self.ciphertext_new_source.try_into()?;
|
||||
let new_spendable_ciphertext = self.new_source_ciphertext.try_into()?;
|
||||
|
||||
self.proof.verify(
|
||||
&ciphertext_lo,
|
||||
|
@ -272,56 +272,56 @@ impl TransferProof {
|
|||
transfer_pubkeys: &pod::TransferPubkeys,
|
||||
ciphertext_lo: &pod::TransferAmountEncryption,
|
||||
ciphertext_hi: &pod::TransferAmountEncryption,
|
||||
ciphertext_new_source: &pod::ElGamalCiphertext,
|
||||
new_source_ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"transfer-proof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_pubkeys.pubkey_source);
|
||||
transcript.append_pubkey(b"pubkey-dest", &transfer_pubkeys.pubkey_dest);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_pubkeys.pubkey_auditor);
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_pubkeys.source_pubkey);
|
||||
transcript.append_pubkey(b"pubkey-dest", &transfer_pubkeys.destination_pubkey);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_pubkeys.auditor_pubkey);
|
||||
|
||||
transcript.append_commitment(b"comm-lo-amount", &ciphertext_lo.commitment);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.handle_source);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.handle_dest);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.handle_auditor);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.source_handle);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.destination_handle);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.auditor_handle);
|
||||
|
||||
transcript.append_commitment(b"comm-hi-amount", &ciphertext_hi.commitment);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.handle_source);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.handle_dest);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.handle_auditor);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.source_handle);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.destination_handle);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.auditor_handle);
|
||||
|
||||
transcript.append_ciphertext(b"ciphertext-new-source", ciphertext_new_source);
|
||||
transcript.append_ciphertext(b"ciphertext-new-source", new_source_ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
(transfer_amount_lo, transfer_amount_hi): (u32, u32),
|
||||
keypair_source: &ElGamalKeypair,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
source_keypair: &ElGamalKeypair,
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
opening_lo: &PedersenOpening,
|
||||
opening_hi: &PedersenOpening,
|
||||
(source_new_balance, ciphertext_new_source): (u64, &ElGamalCiphertext),
|
||||
(source_new_balance, new_source_ciphertext): (u64, &ElGamalCiphertext),
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
// generate a Pedersen commitment for the remaining balance in source
|
||||
let (commitment_new_source, opening_source) = Pedersen::new(source_new_balance);
|
||||
let (commitment_new_source, source_opening) = Pedersen::new(source_new_balance);
|
||||
|
||||
let pod_commitment_new_source: pod::PedersenCommitment = commitment_new_source.into();
|
||||
transcript.append_commitment(b"commitment-new-source", &pod_commitment_new_source);
|
||||
|
||||
// generate equality_proof
|
||||
let equality_proof = CtxtCommEqualityProof::new(
|
||||
keypair_source,
|
||||
ciphertext_new_source,
|
||||
source_keypair,
|
||||
new_source_ciphertext,
|
||||
source_new_balance,
|
||||
&opening_source,
|
||||
&source_opening,
|
||||
transcript,
|
||||
);
|
||||
|
||||
// generate ciphertext validity proof
|
||||
let validity_proof = AggregatedValidityProof::new(
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
(transfer_amount_lo, transfer_amount_hi),
|
||||
(opening_lo, opening_hi),
|
||||
transcript,
|
||||
|
@ -339,7 +339,7 @@ impl TransferProof {
|
|||
TRANSFER_AMOUNT_LO_BIT_LENGTH,
|
||||
TRANSFER_AMOUNT_HI_BIT_LENGTH,
|
||||
],
|
||||
vec![&opening_source, opening_lo, opening_hi],
|
||||
vec![&source_opening, opening_lo, opening_hi],
|
||||
transcript,
|
||||
);
|
||||
|
||||
|
@ -370,7 +370,7 @@ impl TransferProof {
|
|||
//
|
||||
// TODO: we can also consider verifying equality and range proof in a batch
|
||||
equality_proof.verify(
|
||||
&transfer_pubkeys.pubkey_source,
|
||||
&transfer_pubkeys.source_pubkey,
|
||||
ciphertext_new_spendable,
|
||||
&commitment,
|
||||
transcript,
|
||||
|
@ -379,12 +379,15 @@ impl TransferProof {
|
|||
// verify validity proof
|
||||
aggregated_validity_proof.verify(
|
||||
(
|
||||
&transfer_pubkeys.pubkey_dest,
|
||||
&transfer_pubkeys.pubkey_auditor,
|
||||
&transfer_pubkeys.destination_pubkey,
|
||||
&transfer_pubkeys.auditor_pubkey,
|
||||
),
|
||||
(&ciphertext_lo.commitment, &ciphertext_hi.commitment),
|
||||
(&ciphertext_lo.handle_dest, &ciphertext_hi.handle_dest),
|
||||
(&ciphertext_lo.handle_auditor, &ciphertext_hi.handle_auditor),
|
||||
(
|
||||
&ciphertext_lo.destination_handle,
|
||||
&ciphertext_hi.destination_handle,
|
||||
),
|
||||
(&ciphertext_lo.auditor_handle, &ciphertext_hi.auditor_handle),
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
|
@ -409,9 +412,9 @@ impl TransferProof {
|
|||
#[repr(C)]
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
pub struct TransferPubkeys {
|
||||
pub pubkey_source: ElGamalPubkey,
|
||||
pub pubkey_dest: ElGamalPubkey,
|
||||
pub pubkey_auditor: ElGamalPubkey,
|
||||
pub source_pubkey: ElGamalPubkey,
|
||||
pub destination_pubkey: ElGamalPubkey,
|
||||
pub auditor_pubkey: ElGamalPubkey,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
|
@ -419,26 +422,27 @@ impl TransferPubkeys {
|
|||
// TODO: use constructor instead
|
||||
pub fn to_bytes(&self) -> [u8; 96] {
|
||||
let mut bytes = [0u8; 96];
|
||||
bytes[..32].copy_from_slice(&self.pubkey_source.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.pubkey_dest.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.pubkey_auditor.to_bytes());
|
||||
bytes[..32].copy_from_slice(&self.source_pubkey.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.destination_pubkey.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.auditor_pubkey.to_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ProofError> {
|
||||
let bytes = array_ref![bytes, 0, 96];
|
||||
let (pubkey_source, pubkey_dest, pubkey_auditor) = array_refs![bytes, 32, 32, 32];
|
||||
let (source_pubkey, destination_pubkey, auditor_pubkey) = array_refs![bytes, 32, 32, 32];
|
||||
|
||||
let pubkey_source =
|
||||
ElGamalPubkey::from_bytes(pubkey_source).ok_or(ProofError::Verification)?;
|
||||
let pubkey_dest = ElGamalPubkey::from_bytes(pubkey_dest).ok_or(ProofError::Verification)?;
|
||||
let pubkey_auditor =
|
||||
ElGamalPubkey::from_bytes(pubkey_auditor).ok_or(ProofError::Verification)?;
|
||||
let source_pubkey =
|
||||
ElGamalPubkey::from_bytes(source_pubkey).ok_or(ProofError::Verification)?;
|
||||
let destination_pubkey =
|
||||
ElGamalPubkey::from_bytes(destination_pubkey).ok_or(ProofError::Verification)?;
|
||||
let auditor_pubkey =
|
||||
ElGamalPubkey::from_bytes(auditor_pubkey).ok_or(ProofError::Verification)?;
|
||||
|
||||
Ok(Self {
|
||||
pubkey_source,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
source_pubkey,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,10 +63,10 @@ pub struct TransferWithFeeData {
|
|||
pub transfer_with_fee_pubkeys: pod::TransferWithFeePubkeys,
|
||||
|
||||
/// The final spendable ciphertext after the transfer,
|
||||
pub ciphertext_new_source: pod::ElGamalCiphertext,
|
||||
pub new_source_ciphertext: pod::ElGamalCiphertext,
|
||||
|
||||
// transfer fee encryption
|
||||
pub ciphertext_fee: pod::FeeEncryption,
|
||||
pub fee_ciphertext: pod::FeeEncryption,
|
||||
|
||||
// fee parameters
|
||||
pub fee_parameters: pod::FeeParameters,
|
||||
|
@ -79,26 +79,26 @@ pub struct TransferWithFeeData {
|
|||
impl TransferWithFeeData {
|
||||
pub fn new(
|
||||
transfer_amount: u64,
|
||||
(spendable_balance, ciphertext_old_source): (u64, &ElGamalCiphertext),
|
||||
keypair_source: &ElGamalKeypair,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(spendable_balance, old_source_ciphertext): (u64, &ElGamalCiphertext),
|
||||
source_keypair: &ElGamalKeypair,
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
fee_parameters: FeeParameters,
|
||||
pubkey_withdraw_withheld_authority: &ElGamalPubkey,
|
||||
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
|
||||
) -> Result<Self, ProofError> {
|
||||
// split and encrypt transfer amount
|
||||
let (amount_lo, amount_hi) = split_u64_into_u32(transfer_amount);
|
||||
|
||||
let (ciphertext_lo, opening_lo) = TransferAmountEncryption::new(
|
||||
amount_lo,
|
||||
&keypair_source.public,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
&source_keypair.public,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
);
|
||||
let (ciphertext_hi, opening_hi) = TransferAmountEncryption::new(
|
||||
amount_hi,
|
||||
&keypair_source.public,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
&source_keypair.public,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
);
|
||||
|
||||
// subtract transfer amount from the spendable ciphertext
|
||||
|
@ -108,15 +108,15 @@ impl TransferWithFeeData {
|
|||
|
||||
let transfer_amount_lo_source = ElGamalCiphertext {
|
||||
commitment: ciphertext_lo.commitment,
|
||||
handle: ciphertext_lo.handle_source,
|
||||
handle: ciphertext_lo.source_handle,
|
||||
};
|
||||
|
||||
let transfer_amount_hi_source = ElGamalCiphertext {
|
||||
commitment: ciphertext_hi.commitment,
|
||||
handle: ciphertext_hi.handle_source,
|
||||
handle: ciphertext_hi.source_handle,
|
||||
};
|
||||
|
||||
let ciphertext_new_source = ciphertext_old_source
|
||||
let new_source_ciphertext = old_source_ciphertext
|
||||
- combine_u32_ciphertexts(&transfer_amount_lo_source, &transfer_amount_hi_source);
|
||||
|
||||
// calculate and encrypt fee
|
||||
|
@ -126,43 +126,42 @@ impl TransferWithFeeData {
|
|||
let below_max = u64::ct_gt(&fee_parameters.maximum_fee, &fee_amount);
|
||||
let fee_to_encrypt =
|
||||
u64::conditional_select(&fee_parameters.maximum_fee, &fee_amount, below_max);
|
||||
// u64::conditional_select(&fee_amount, &fee_parameters.maximum_fee, below_max);
|
||||
|
||||
let (ciphertext_fee, opening_fee) = FeeEncryption::new(
|
||||
let (fee_ciphertext, opening_fee) = FeeEncryption::new(
|
||||
fee_to_encrypt,
|
||||
pubkey_dest,
|
||||
pubkey_withdraw_withheld_authority,
|
||||
destination_pubkey,
|
||||
withdraw_withheld_authority_pubkey,
|
||||
);
|
||||
|
||||
// generate transcript and append all public inputs
|
||||
let pod_transfer_with_fee_pubkeys = pod::TransferWithFeePubkeys {
|
||||
pubkey_source: keypair_source.public.into(),
|
||||
pubkey_dest: (*pubkey_dest).into(),
|
||||
pubkey_auditor: (*pubkey_auditor).into(),
|
||||
pubkey_withdraw_withheld_authority: (*pubkey_withdraw_withheld_authority).into(),
|
||||
source_pubkey: source_keypair.public.into(),
|
||||
destination_pubkey: (*destination_pubkey).into(),
|
||||
auditor_pubkey: (*auditor_pubkey).into(),
|
||||
withdraw_withheld_authority_pubkey: (*withdraw_withheld_authority_pubkey).into(),
|
||||
};
|
||||
let pod_ciphertext_lo: pod::TransferAmountEncryption = ciphertext_lo.to_pod();
|
||||
let pod_ciphertext_hi: pod::TransferAmountEncryption = ciphertext_hi.to_pod();
|
||||
let pod_ciphertext_new_source: pod::ElGamalCiphertext = ciphertext_new_source.into();
|
||||
let pod_ciphertext_fee: pod::FeeEncryption = ciphertext_fee.to_pod();
|
||||
let pod_new_source_ciphertext: pod::ElGamalCiphertext = new_source_ciphertext.into();
|
||||
let pod_fee_ciphertext: pod::FeeEncryption = fee_ciphertext.to_pod();
|
||||
|
||||
let mut transcript = TransferWithFeeProof::transcript_new(
|
||||
&pod_transfer_with_fee_pubkeys,
|
||||
&pod_ciphertext_lo,
|
||||
&pod_ciphertext_hi,
|
||||
&pod_ciphertext_new_source,
|
||||
&pod_ciphertext_fee,
|
||||
&pod_new_source_ciphertext,
|
||||
&pod_fee_ciphertext,
|
||||
);
|
||||
|
||||
let proof = TransferWithFeeProof::new(
|
||||
(amount_lo, &ciphertext_lo, &opening_lo),
|
||||
(amount_hi, &ciphertext_hi, &opening_hi),
|
||||
keypair_source,
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
(new_spendable_balance, &ciphertext_new_source),
|
||||
(fee_amount, &ciphertext_fee, &opening_fee),
|
||||
source_keypair,
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
(new_spendable_balance, &new_source_ciphertext),
|
||||
(fee_to_encrypt, &fee_ciphertext, &opening_fee),
|
||||
delta_fee,
|
||||
pubkey_withdraw_withheld_authority,
|
||||
withdraw_withheld_authority_pubkey,
|
||||
fee_parameters,
|
||||
&mut transcript,
|
||||
);
|
||||
|
@ -171,8 +170,8 @@ impl TransferWithFeeData {
|
|||
ciphertext_lo: pod_ciphertext_lo,
|
||||
ciphertext_hi: pod_ciphertext_hi,
|
||||
transfer_with_fee_pubkeys: pod_transfer_with_fee_pubkeys,
|
||||
ciphertext_new_source: pod_ciphertext_new_source,
|
||||
ciphertext_fee: pod_ciphertext_fee,
|
||||
new_source_ciphertext: pod_new_source_ciphertext,
|
||||
fee_ciphertext: pod_fee_ciphertext,
|
||||
fee_parameters: fee_parameters.into(),
|
||||
proof,
|
||||
})
|
||||
|
@ -183,9 +182,9 @@ impl TransferWithFeeData {
|
|||
let ciphertext_lo: TransferAmountEncryption = self.ciphertext_lo.try_into()?;
|
||||
|
||||
let handle_lo = match role {
|
||||
Role::Source => ciphertext_lo.handle_source,
|
||||
Role::Dest => ciphertext_lo.handle_dest,
|
||||
Role::Auditor => ciphertext_lo.handle_auditor,
|
||||
Role::Source => ciphertext_lo.source_handle,
|
||||
Role::Dest => ciphertext_lo.destination_handle,
|
||||
Role::Auditor => ciphertext_lo.auditor_handle,
|
||||
};
|
||||
|
||||
Ok(ElGamalCiphertext {
|
||||
|
@ -199,9 +198,9 @@ impl TransferWithFeeData {
|
|||
let ciphertext_hi: TransferAmountEncryption = self.ciphertext_hi.try_into()?;
|
||||
|
||||
let handle_hi = match role {
|
||||
Role::Source => ciphertext_hi.handle_source,
|
||||
Role::Dest => ciphertext_hi.handle_dest,
|
||||
Role::Auditor => ciphertext_hi.handle_auditor,
|
||||
Role::Source => ciphertext_hi.source_handle,
|
||||
Role::Dest => ciphertext_hi.destination_handle,
|
||||
Role::Auditor => ciphertext_hi.auditor_handle,
|
||||
};
|
||||
|
||||
Ok(ElGamalCiphertext {
|
||||
|
@ -238,24 +237,24 @@ impl Verifiable for TransferWithFeeData {
|
|||
&self.transfer_with_fee_pubkeys,
|
||||
&self.ciphertext_lo,
|
||||
&self.ciphertext_hi,
|
||||
&self.ciphertext_new_source,
|
||||
&self.ciphertext_fee,
|
||||
&self.new_source_ciphertext,
|
||||
&self.fee_ciphertext,
|
||||
);
|
||||
|
||||
let ciphertext_lo = self.ciphertext_lo.try_into()?;
|
||||
let ciphertext_hi = self.ciphertext_hi.try_into()?;
|
||||
let pubkeys_transfer_with_fee = self.transfer_with_fee_pubkeys.try_into()?;
|
||||
let ciphertext_new_source = self.ciphertext_new_source.try_into()?;
|
||||
let new_source_ciphertext = self.new_source_ciphertext.try_into()?;
|
||||
|
||||
let ciphertext_fee = self.ciphertext_fee.try_into()?;
|
||||
let fee_ciphertext = self.fee_ciphertext.try_into()?;
|
||||
let fee_parameters = self.fee_parameters.into();
|
||||
|
||||
self.proof.verify(
|
||||
&ciphertext_lo,
|
||||
&ciphertext_hi,
|
||||
&pubkeys_transfer_with_fee,
|
||||
&ciphertext_new_source,
|
||||
&ciphertext_fee,
|
||||
&new_source_ciphertext,
|
||||
&fee_ciphertext,
|
||||
fee_parameters,
|
||||
&mut transcript,
|
||||
)
|
||||
|
@ -266,12 +265,12 @@ impl Verifiable for TransferWithFeeData {
|
|||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
pub struct TransferWithFeeProof {
|
||||
pub commitment_new_source: pod::PedersenCommitment,
|
||||
pub commitment_claimed: pod::PedersenCommitment,
|
||||
pub new_source_commitment: pod::PedersenCommitment,
|
||||
pub claimed_commitment: pod::PedersenCommitment,
|
||||
pub equality_proof: pod::CtxtCommEqualityProof,
|
||||
pub ciphertext_amount_validity_proof: pod::AggregatedValidityProof,
|
||||
pub fee_sigma_proof: pod::FeeSigmaProof,
|
||||
pub ciphertext_fee_validity_proof: pod::ValidityProof,
|
||||
pub fee_ciphertext_validity_proof: pod::ValidityProof,
|
||||
pub range_proof: pod::RangeProof256,
|
||||
}
|
||||
|
||||
|
@ -282,36 +281,39 @@ impl TransferWithFeeProof {
|
|||
transfer_with_fee_pubkeys: &pod::TransferWithFeePubkeys,
|
||||
ciphertext_lo: &pod::TransferAmountEncryption,
|
||||
ciphertext_hi: &pod::TransferAmountEncryption,
|
||||
ciphertext_new_source: &pod::ElGamalCiphertext,
|
||||
ciphertext_fee: &pod::FeeEncryption,
|
||||
new_source_ciphertext: &pod::ElGamalCiphertext,
|
||||
fee_ciphertext: &pod::FeeEncryption,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"FeeProof");
|
||||
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_with_fee_pubkeys.pubkey_source);
|
||||
transcript.append_pubkey(b"pubkey-dest", &transfer_with_fee_pubkeys.pubkey_dest);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_with_fee_pubkeys.pubkey_auditor);
|
||||
transcript.append_pubkey(b"pubkey-source", &transfer_with_fee_pubkeys.source_pubkey);
|
||||
transcript.append_pubkey(
|
||||
b"pubkey_withdraw_withheld_authority",
|
||||
&transfer_with_fee_pubkeys.pubkey_withdraw_withheld_authority,
|
||||
b"pubkey-dest",
|
||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||
);
|
||||
transcript.append_pubkey(b"pubkey-auditor", &transfer_with_fee_pubkeys.auditor_pubkey);
|
||||
transcript.append_pubkey(
|
||||
b"withdraw_withheld_authority_pubkey",
|
||||
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
|
||||
);
|
||||
|
||||
transcript.append_commitment(b"comm-lo-amount", &ciphertext_lo.commitment);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.handle_source);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.handle_dest);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.handle_auditor);
|
||||
transcript.append_handle(b"handle-lo-source", &ciphertext_lo.source_handle);
|
||||
transcript.append_handle(b"handle-lo-dest", &ciphertext_lo.destination_handle);
|
||||
transcript.append_handle(b"handle-lo-auditor", &ciphertext_lo.auditor_handle);
|
||||
|
||||
transcript.append_commitment(b"comm-hi-amount", &ciphertext_hi.commitment);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.handle_source);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.handle_dest);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.handle_auditor);
|
||||
transcript.append_handle(b"handle-hi-source", &ciphertext_hi.source_handle);
|
||||
transcript.append_handle(b"handle-hi-dest", &ciphertext_hi.destination_handle);
|
||||
transcript.append_handle(b"handle-hi-auditor", &ciphertext_hi.auditor_handle);
|
||||
|
||||
transcript.append_ciphertext(b"ctxt-new-source", ciphertext_new_source);
|
||||
transcript.append_ciphertext(b"ctxt-new-source", new_source_ciphertext);
|
||||
|
||||
transcript.append_commitment(b"comm-fee", &ciphertext_fee.commitment);
|
||||
transcript.append_handle(b"fee-dest-handle", &ciphertext_fee.handle_dest);
|
||||
transcript.append_commitment(b"comm-fee", &fee_ciphertext.commitment);
|
||||
transcript.append_handle(b"fee-dest-handle", &fee_ciphertext.destination_handle);
|
||||
transcript.append_handle(
|
||||
b"handle-fee-auditor",
|
||||
&ciphertext_fee.handle_withdraw_withheld_authority,
|
||||
&fee_ciphertext.withdraw_withheld_authority_handle,
|
||||
);
|
||||
|
||||
transcript
|
||||
|
@ -322,13 +324,13 @@ impl TransferWithFeeProof {
|
|||
pub fn new(
|
||||
transfer_amount_lo_data: (u32, &TransferAmountEncryption, &PedersenOpening),
|
||||
transfer_amount_hi_data: (u32, &TransferAmountEncryption, &PedersenOpening),
|
||||
keypair_source: &ElGamalKeypair,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(source_new_balance, ciphertext_new_source): (u64, &ElGamalCiphertext),
|
||||
source_keypair: &ElGamalKeypair,
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(source_new_balance, new_source_ciphertext): (u64, &ElGamalCiphertext),
|
||||
|
||||
(fee_amount, ciphertext_fee, opening_fee): (u64, &FeeEncryption, &PedersenOpening),
|
||||
(fee_amount, fee_ciphertext, opening_fee): (u64, &FeeEncryption, &PedersenOpening),
|
||||
delta_fee: u64,
|
||||
pubkey_withdraw_withheld_authority: &ElGamalPubkey,
|
||||
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
|
||||
fee_parameters: FeeParameters,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
|
@ -336,19 +338,19 @@ impl TransferWithFeeProof {
|
|||
let (transfer_amount_hi, ciphertext_hi, opening_hi) = transfer_amount_hi_data;
|
||||
|
||||
// generate a Pedersen commitment for the remaining balance in source
|
||||
let (commitment_new_source, opening_source) = Pedersen::new(source_new_balance);
|
||||
let (commitment_claimed, opening_claimed) = Pedersen::new(delta_fee);
|
||||
let (new_source_commitment, opening_source) = Pedersen::new(source_new_balance);
|
||||
let (claimed_commitment, opening_claimed) = Pedersen::new(delta_fee);
|
||||
|
||||
let pod_commitment_new_source: pod::PedersenCommitment = commitment_new_source.into();
|
||||
let pod_commitment_claimed: pod::PedersenCommitment = commitment_claimed.into();
|
||||
let pod_new_source_commitment: pod::PedersenCommitment = new_source_commitment.into();
|
||||
let pod_claimed_commitment: pod::PedersenCommitment = claimed_commitment.into();
|
||||
|
||||
transcript.append_commitment(b"commitment-new-source", &pod_commitment_new_source);
|
||||
transcript.append_commitment(b"commitment-claimed", &pod_commitment_claimed);
|
||||
transcript.append_commitment(b"commitment-new-source", &pod_new_source_commitment);
|
||||
transcript.append_commitment(b"commitment-claimed", &pod_claimed_commitment);
|
||||
|
||||
// generate equality_proof
|
||||
let equality_proof = CtxtCommEqualityProof::new(
|
||||
keypair_source,
|
||||
ciphertext_new_source,
|
||||
source_keypair,
|
||||
new_source_ciphertext,
|
||||
source_new_balance,
|
||||
&opening_source,
|
||||
transcript,
|
||||
|
@ -356,29 +358,29 @@ impl TransferWithFeeProof {
|
|||
|
||||
// generate ciphertext validity proof
|
||||
let ciphertext_amount_validity_proof = AggregatedValidityProof::new(
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
(transfer_amount_lo, transfer_amount_hi),
|
||||
(opening_lo, opening_hi),
|
||||
transcript,
|
||||
);
|
||||
|
||||
let (commitment_delta, opening_delta) = compute_delta_commitment_and_opening(
|
||||
let (delta_commitment, opening_delta) = compute_delta_commitment_and_opening(
|
||||
(&ciphertext_lo.commitment, opening_lo),
|
||||
(&ciphertext_hi.commitment, opening_hi),
|
||||
(&ciphertext_fee.commitment, opening_fee),
|
||||
(&fee_ciphertext.commitment, opening_fee),
|
||||
fee_parameters.fee_rate_basis_points,
|
||||
);
|
||||
|
||||
let fee_sigma_proof = FeeSigmaProof::new(
|
||||
(fee_amount, &ciphertext_fee.commitment, opening_fee),
|
||||
(delta_fee, &commitment_delta, &opening_delta),
|
||||
(&commitment_claimed, &opening_claimed),
|
||||
(fee_amount, &fee_ciphertext.commitment, opening_fee),
|
||||
(delta_fee, &delta_commitment, &opening_delta),
|
||||
(&claimed_commitment, &opening_claimed),
|
||||
fee_parameters.maximum_fee,
|
||||
transcript,
|
||||
);
|
||||
|
||||
let ciphertext_fee_validity_proof = ValidityProof::new(
|
||||
(pubkey_dest, pubkey_withdraw_withheld_authority),
|
||||
let fee_ciphertext_validity_proof = ValidityProof::new(
|
||||
(destination_pubkey, withdraw_withheld_authority_pubkey),
|
||||
fee_amount,
|
||||
opening_fee,
|
||||
transcript,
|
||||
|
@ -411,12 +413,12 @@ impl TransferWithFeeProof {
|
|||
);
|
||||
|
||||
Self {
|
||||
commitment_new_source: pod_commitment_new_source,
|
||||
commitment_claimed: pod_commitment_claimed,
|
||||
new_source_commitment: pod_new_source_commitment,
|
||||
claimed_commitment: pod_claimed_commitment,
|
||||
equality_proof: equality_proof.into(),
|
||||
ciphertext_amount_validity_proof: ciphertext_amount_validity_proof.into(),
|
||||
fee_sigma_proof: fee_sigma_proof.into(),
|
||||
ciphertext_fee_validity_proof: ciphertext_fee_validity_proof.into(),
|
||||
fee_ciphertext_validity_proof: fee_ciphertext_validity_proof.into(),
|
||||
range_proof: range_proof.try_into().expect("range proof: length error"),
|
||||
}
|
||||
}
|
||||
|
@ -428,81 +430,86 @@ impl TransferWithFeeProof {
|
|||
transfer_with_fee_pubkeys: &TransferWithFeePubkeys,
|
||||
new_spendable_ciphertext: &ElGamalCiphertext,
|
||||
|
||||
ciphertext_fee: &FeeEncryption,
|
||||
fee_ciphertext: &FeeEncryption,
|
||||
fee_parameters: FeeParameters,
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), ProofError> {
|
||||
transcript.append_commitment(b"commitment-new-source", &self.commitment_new_source);
|
||||
transcript.append_commitment(b"commitment-claimed", &self.commitment_claimed);
|
||||
transcript.append_commitment(b"commitment-new-source", &self.new_source_commitment);
|
||||
transcript.append_commitment(b"commitment-claimed", &self.claimed_commitment);
|
||||
|
||||
let commitment_new_source: PedersenCommitment = self.commitment_new_source.try_into()?;
|
||||
let commitment_claimed: PedersenCommitment = self.commitment_claimed.try_into()?;
|
||||
let new_source_commitment: PedersenCommitment = self.new_source_commitment.try_into()?;
|
||||
let claimed_commitment: PedersenCommitment = self.claimed_commitment.try_into()?;
|
||||
|
||||
let equality_proof: CtxtCommEqualityProof = self.equality_proof.try_into()?;
|
||||
let ciphertext_amount_validity_proof: AggregatedValidityProof =
|
||||
self.ciphertext_amount_validity_proof.try_into()?;
|
||||
let fee_sigma_proof: FeeSigmaProof = self.fee_sigma_proof.try_into()?;
|
||||
let ciphertext_fee_validity_proof: ValidityProof =
|
||||
self.ciphertext_fee_validity_proof.try_into()?;
|
||||
let fee_ciphertext_validity_proof: ValidityProof =
|
||||
self.fee_ciphertext_validity_proof.try_into()?;
|
||||
let range_proof: RangeProof = self.range_proof.try_into()?;
|
||||
|
||||
// verify equality proof
|
||||
equality_proof.verify(
|
||||
&transfer_with_fee_pubkeys.pubkey_source,
|
||||
&transfer_with_fee_pubkeys.source_pubkey,
|
||||
new_spendable_ciphertext,
|
||||
&commitment_new_source,
|
||||
&new_source_commitment,
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
println!("here");
|
||||
|
||||
// verify that the transfer amount is encrypted correctly
|
||||
ciphertext_amount_validity_proof.verify(
|
||||
(
|
||||
&transfer_with_fee_pubkeys.pubkey_dest,
|
||||
&transfer_with_fee_pubkeys.pubkey_auditor,
|
||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||
&transfer_with_fee_pubkeys.auditor_pubkey,
|
||||
),
|
||||
(&ciphertext_lo.commitment, &ciphertext_hi.commitment),
|
||||
(&ciphertext_lo.handle_dest, &ciphertext_hi.handle_dest),
|
||||
(&ciphertext_lo.handle_auditor, &ciphertext_hi.handle_auditor),
|
||||
(
|
||||
&ciphertext_lo.destination_handle,
|
||||
&ciphertext_hi.destination_handle,
|
||||
),
|
||||
(&ciphertext_lo.auditor_handle, &ciphertext_hi.auditor_handle),
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
// verify fee sigma proof
|
||||
let commitment_delta = compute_delta_commitment(
|
||||
let delta_commitment = compute_delta_commitment(
|
||||
&ciphertext_lo.commitment,
|
||||
&ciphertext_hi.commitment,
|
||||
&ciphertext_fee.commitment,
|
||||
&fee_ciphertext.commitment,
|
||||
fee_parameters.fee_rate_basis_points,
|
||||
);
|
||||
|
||||
fee_sigma_proof.verify(
|
||||
&ciphertext_fee.commitment,
|
||||
&commitment_delta,
|
||||
&commitment_claimed,
|
||||
&fee_ciphertext.commitment,
|
||||
&delta_commitment,
|
||||
&claimed_commitment,
|
||||
fee_parameters.maximum_fee,
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
ciphertext_fee_validity_proof.verify(
|
||||
&ciphertext_fee.commitment,
|
||||
fee_ciphertext_validity_proof.verify(
|
||||
&fee_ciphertext.commitment,
|
||||
(
|
||||
&transfer_with_fee_pubkeys.pubkey_dest,
|
||||
&transfer_with_fee_pubkeys.pubkey_withdraw_withheld_authority,
|
||||
&transfer_with_fee_pubkeys.destination_pubkey,
|
||||
&transfer_with_fee_pubkeys.withdraw_withheld_authority_pubkey,
|
||||
),
|
||||
(
|
||||
&ciphertext_fee.handle_dest,
|
||||
&ciphertext_fee.handle_withdraw_withheld_authority,
|
||||
&fee_ciphertext.destination_handle,
|
||||
&fee_ciphertext.withdraw_withheld_authority_handle,
|
||||
),
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
let commitment_claimed_negated = &(*COMMITMENT_MAX_FEE_BASIS_POINTS) - &commitment_claimed;
|
||||
let claimed_commitment_negated = &(*COMMITMENT_MAX_FEE_BASIS_POINTS) - &claimed_commitment;
|
||||
range_proof.verify(
|
||||
vec![
|
||||
&commitment_new_source,
|
||||
&new_source_commitment,
|
||||
&ciphertext_lo.commitment,
|
||||
&ciphertext_hi.commitment,
|
||||
&commitment_claimed,
|
||||
&commitment_claimed_negated,
|
||||
&claimed_commitment,
|
||||
&claimed_commitment_negated,
|
||||
],
|
||||
vec![64, 32, 32, 64, 64],
|
||||
transcript,
|
||||
|
@ -517,42 +524,43 @@ impl TransferWithFeeProof {
|
|||
#[repr(C)]
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
pub struct TransferWithFeePubkeys {
|
||||
pub pubkey_source: ElGamalPubkey,
|
||||
pub pubkey_dest: ElGamalPubkey,
|
||||
pub pubkey_auditor: ElGamalPubkey,
|
||||
pub pubkey_withdraw_withheld_authority: ElGamalPubkey,
|
||||
pub source_pubkey: ElGamalPubkey,
|
||||
pub destination_pubkey: ElGamalPubkey,
|
||||
pub auditor_pubkey: ElGamalPubkey,
|
||||
pub withdraw_withheld_authority_pubkey: ElGamalPubkey,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
impl TransferWithFeePubkeys {
|
||||
pub fn to_bytes(&self) -> [u8; 128] {
|
||||
let mut bytes = [0u8; 128];
|
||||
bytes[..32].copy_from_slice(&self.pubkey_source.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.pubkey_dest.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.pubkey_auditor.to_bytes());
|
||||
bytes[96..128].copy_from_slice(&self.pubkey_withdraw_withheld_authority.to_bytes());
|
||||
bytes[..32].copy_from_slice(&self.source_pubkey.to_bytes());
|
||||
bytes[32..64].copy_from_slice(&self.destination_pubkey.to_bytes());
|
||||
bytes[64..96].copy_from_slice(&self.auditor_pubkey.to_bytes());
|
||||
bytes[96..128].copy_from_slice(&self.withdraw_withheld_authority_pubkey.to_bytes());
|
||||
bytes
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ProofError> {
|
||||
let bytes = array_ref![bytes, 0, 128];
|
||||
let (pubkey_source, pubkey_dest, pubkey_auditor, pubkey_withdraw_withheld_authority) =
|
||||
let (source_pubkey, destination_pubkey, auditor_pubkey, withdraw_withheld_authority_pubkey) =
|
||||
array_refs![bytes, 32, 32, 32, 32];
|
||||
|
||||
let pubkey_source =
|
||||
ElGamalPubkey::from_bytes(pubkey_source).ok_or(ProofError::Verification)?;
|
||||
let pubkey_dest = ElGamalPubkey::from_bytes(pubkey_dest).ok_or(ProofError::Verification)?;
|
||||
let pubkey_auditor =
|
||||
ElGamalPubkey::from_bytes(pubkey_auditor).ok_or(ProofError::Verification)?;
|
||||
let pubkey_withdraw_withheld_authority =
|
||||
ElGamalPubkey::from_bytes(pubkey_withdraw_withheld_authority)
|
||||
let source_pubkey =
|
||||
ElGamalPubkey::from_bytes(source_pubkey).ok_or(ProofError::Verification)?;
|
||||
let destination_pubkey =
|
||||
ElGamalPubkey::from_bytes(destination_pubkey).ok_or(ProofError::Verification)?;
|
||||
let auditor_pubkey =
|
||||
ElGamalPubkey::from_bytes(auditor_pubkey).ok_or(ProofError::Verification)?;
|
||||
let withdraw_withheld_authority_pubkey =
|
||||
ElGamalPubkey::from_bytes(withdraw_withheld_authority_pubkey)
|
||||
.ok_or(ProofError::Verification)?;
|
||||
|
||||
Ok(Self {
|
||||
pubkey_source,
|
||||
pubkey_dest,
|
||||
pubkey_auditor,
|
||||
pubkey_withdraw_withheld_authority,
|
||||
source_pubkey,
|
||||
destination_pubkey,
|
||||
auditor_pubkey,
|
||||
withdraw_withheld_authority_pubkey,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -562,22 +570,23 @@ impl TransferWithFeePubkeys {
|
|||
#[cfg(not(target_arch = "bpf"))]
|
||||
pub struct FeeEncryption {
|
||||
pub commitment: PedersenCommitment,
|
||||
pub handle_dest: DecryptHandle,
|
||||
pub handle_withdraw_withheld_authority: DecryptHandle,
|
||||
pub destination_handle: DecryptHandle,
|
||||
pub withdraw_withheld_authority_handle: DecryptHandle,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
impl FeeEncryption {
|
||||
pub fn new(
|
||||
amount: u64,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
pubkey_withdraw_withheld: &ElGamalPubkey,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
withdraw_withheld_authority_pubkey: &ElGamalPubkey,
|
||||
) -> (Self, PedersenOpening) {
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
let fee_encryption = Self {
|
||||
commitment,
|
||||
handle_dest: pubkey_dest.decrypt_handle(&opening),
|
||||
handle_withdraw_withheld_authority: pubkey_withdraw_withheld.decrypt_handle(&opening),
|
||||
destination_handle: destination_pubkey.decrypt_handle(&opening),
|
||||
withdraw_withheld_authority_handle: withdraw_withheld_authority_pubkey
|
||||
.decrypt_handle(&opening),
|
||||
};
|
||||
|
||||
(fee_encryption, opening)
|
||||
|
@ -586,8 +595,8 @@ impl FeeEncryption {
|
|||
pub fn to_pod(&self) -> pod::FeeEncryption {
|
||||
pod::FeeEncryption {
|
||||
commitment: self.commitment.into(),
|
||||
handle_dest: self.handle_dest.into(),
|
||||
handle_withdraw_withheld_authority: self.handle_withdraw_withheld_authority.into(),
|
||||
destination_handle: self.destination_handle.into(),
|
||||
withdraw_withheld_authority_handle: self.withdraw_withheld_authority_handle.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -640,30 +649,30 @@ fn calculate_fee(transfer_amount: u64, fee_rate_basis_points: u16) -> (u64, u64)
|
|||
fn compute_delta_commitment_and_opening(
|
||||
(commitment_lo, opening_lo): (&PedersenCommitment, &PedersenOpening),
|
||||
(commitment_hi, opening_hi): (&PedersenCommitment, &PedersenOpening),
|
||||
(commitment_fee, opening_fee): (&PedersenCommitment, &PedersenOpening),
|
||||
(fee_commitment, opening_fee): (&PedersenCommitment, &PedersenOpening),
|
||||
fee_rate_basis_points: u16,
|
||||
) -> (PedersenCommitment, PedersenOpening) {
|
||||
let fee_rate_scalar = Scalar::from(fee_rate_basis_points);
|
||||
|
||||
let commitment_delta = commitment_fee * Scalar::from(MAX_FEE_BASIS_POINTS)
|
||||
let delta_commitment = fee_commitment * Scalar::from(MAX_FEE_BASIS_POINTS)
|
||||
- &(&combine_u32_commitments(commitment_lo, commitment_hi) * &fee_rate_scalar);
|
||||
|
||||
let opening_delta = opening_fee * Scalar::from(MAX_FEE_BASIS_POINTS)
|
||||
- &(&combine_u32_openings(opening_lo, opening_hi) * &fee_rate_scalar);
|
||||
|
||||
(commitment_delta, opening_delta)
|
||||
(delta_commitment, opening_delta)
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
fn compute_delta_commitment(
|
||||
commitment_lo: &PedersenCommitment,
|
||||
commitment_hi: &PedersenCommitment,
|
||||
commitment_fee: &PedersenCommitment,
|
||||
fee_commitment: &PedersenCommitment,
|
||||
fee_rate_basis_points: u16,
|
||||
) -> PedersenCommitment {
|
||||
let fee_rate_scalar = Scalar::from(fee_rate_basis_points);
|
||||
|
||||
commitment_fee * Scalar::from(MAX_FEE_BASIS_POINTS)
|
||||
fee_commitment * Scalar::from(MAX_FEE_BASIS_POINTS)
|
||||
- &(&combine_u32_commitments(commitment_lo, commitment_hi) * &fee_rate_scalar)
|
||||
}
|
||||
|
||||
|
@ -673,28 +682,28 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_fee_correctness() {
|
||||
let keypair_source = ElGamalKeypair::new_rand();
|
||||
let pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let pubkey_withdraw_withheld_authority = ElGamalKeypair::new_rand().public;
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let withdraw_withheld_authority_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let spendable_balance: u64 = 120;
|
||||
let spendable_ciphertext = keypair_source.public.encrypt(spendable_balance);
|
||||
let spendable_ciphertext = source_keypair.public.encrypt(spendable_balance);
|
||||
|
||||
let transfer_amount: u64 = 100;
|
||||
|
||||
let fee_parameters = FeeParameters {
|
||||
fee_rate_basis_points: 100,
|
||||
fee_rate_basis_points: 400,
|
||||
maximum_fee: 3,
|
||||
};
|
||||
|
||||
let fee_data = TransferWithFeeData::new(
|
||||
transfer_amount,
|
||||
(spendable_balance, &spendable_ciphertext),
|
||||
&keypair_source,
|
||||
(&pubkey_dest, &pubkey_auditor),
|
||||
&source_keypair,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
fee_parameters,
|
||||
&pubkey_withdraw_withheld_authority,
|
||||
&withdraw_withheld_authority_pubkey,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ use {
|
|||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct WithdrawWithheldTokensData {
|
||||
pub pubkey_withdraw_withheld_authority: pod::ElGamalPubkey,
|
||||
pub withdraw_withheld_authority_pubkey: pod::ElGamalPubkey,
|
||||
|
||||
pub pubkey_dest: pod::ElGamalPubkey,
|
||||
pub destination_pubkey: pod::ElGamalPubkey,
|
||||
|
||||
pub ciphertext_withdraw_withheld_authority: pod::ElGamalCiphertext,
|
||||
pub withdraw_withheld_authority_ciphertext: pod::ElGamalCiphertext,
|
||||
|
||||
pub ciphertext_dest: pod::ElGamalCiphertext,
|
||||
pub destination_ciphertext: pod::ElGamalCiphertext,
|
||||
|
||||
pub proof: WithdrawWithheldTokensProof,
|
||||
}
|
||||
|
@ -42,42 +42,42 @@ pub struct WithdrawWithheldTokensData {
|
|||
impl WithdrawWithheldTokensData {
|
||||
#[cfg(not(target_arch = "bpf"))]
|
||||
pub fn new(
|
||||
keypair_withdraw_withheld_authority: &ElGamalKeypair,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
ciphertext_withdraw_withheld_authority: &ElGamalCiphertext,
|
||||
withdraw_withheld_authority_keypair: &ElGamalKeypair,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
withdraw_withheld_authority_ciphertext: &ElGamalCiphertext,
|
||||
amount: u64,
|
||||
) -> Result<Self, ProofError> {
|
||||
let opening_dest = PedersenOpening::new_rand();
|
||||
let ciphertext_dest = pubkey_dest.encrypt_with(amount, &opening_dest);
|
||||
let destination_opening = PedersenOpening::new_rand();
|
||||
let destination_ciphertext = destination_pubkey.encrypt_with(amount, &destination_opening);
|
||||
|
||||
let pod_pubkey_withdraw_withheld_authority =
|
||||
pod::ElGamalPubkey(keypair_withdraw_withheld_authority.public.to_bytes());
|
||||
let pod_pubkey_dest = pod::ElGamalPubkey(pubkey_dest.to_bytes());
|
||||
let pod_ciphertext_withdraw_withheld_authority =
|
||||
pod::ElGamalCiphertext(ciphertext_withdraw_withheld_authority.to_bytes());
|
||||
let pod_ciphertext_dest = pod::ElGamalCiphertext(ciphertext_dest.to_bytes());
|
||||
let pod_withdraw_withheld_authority_pubkey =
|
||||
pod::ElGamalPubkey(withdraw_withheld_authority_keypair.public.to_bytes());
|
||||
let pod_destination_pubkey = pod::ElGamalPubkey(destination_pubkey.to_bytes());
|
||||
let pod_withdraw_withheld_authority_ciphertext =
|
||||
pod::ElGamalCiphertext(withdraw_withheld_authority_ciphertext.to_bytes());
|
||||
let pod_destination_ciphertext = pod::ElGamalCiphertext(destination_ciphertext.to_bytes());
|
||||
|
||||
let mut transcript = WithdrawWithheldTokensProof::transcript_new(
|
||||
&pod_pubkey_withdraw_withheld_authority,
|
||||
&pod_pubkey_dest,
|
||||
&pod_ciphertext_withdraw_withheld_authority,
|
||||
&pod_ciphertext_dest,
|
||||
&pod_withdraw_withheld_authority_pubkey,
|
||||
&pod_destination_pubkey,
|
||||
&pod_withdraw_withheld_authority_ciphertext,
|
||||
&pod_destination_ciphertext,
|
||||
);
|
||||
|
||||
let proof = WithdrawWithheldTokensProof::new(
|
||||
keypair_withdraw_withheld_authority,
|
||||
pubkey_dest,
|
||||
ciphertext_withdraw_withheld_authority,
|
||||
withdraw_withheld_authority_keypair,
|
||||
destination_pubkey,
|
||||
withdraw_withheld_authority_ciphertext,
|
||||
amount,
|
||||
&opening_dest,
|
||||
&destination_opening,
|
||||
&mut transcript,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
pubkey_withdraw_withheld_authority: pod_pubkey_withdraw_withheld_authority,
|
||||
pubkey_dest: pod_pubkey_dest,
|
||||
ciphertext_withdraw_withheld_authority: pod_ciphertext_withdraw_withheld_authority,
|
||||
ciphertext_dest: pod_ciphertext_dest,
|
||||
withdraw_withheld_authority_pubkey: pod_withdraw_withheld_authority_pubkey,
|
||||
destination_pubkey: pod_destination_pubkey,
|
||||
withdraw_withheld_authority_ciphertext: pod_withdraw_withheld_authority_ciphertext,
|
||||
destination_ciphertext: pod_destination_ciphertext,
|
||||
proof,
|
||||
})
|
||||
}
|
||||
|
@ -87,24 +87,24 @@ impl WithdrawWithheldTokensData {
|
|||
impl Verifiable for WithdrawWithheldTokensData {
|
||||
fn verify(&self) -> Result<(), ProofError> {
|
||||
let mut transcript = WithdrawWithheldTokensProof::transcript_new(
|
||||
&self.pubkey_withdraw_withheld_authority,
|
||||
&self.pubkey_dest,
|
||||
&self.ciphertext_withdraw_withheld_authority,
|
||||
&self.ciphertext_dest,
|
||||
&self.withdraw_withheld_authority_pubkey,
|
||||
&self.destination_pubkey,
|
||||
&self.withdraw_withheld_authority_ciphertext,
|
||||
&self.destination_ciphertext,
|
||||
);
|
||||
|
||||
let pubkey_withdraw_withheld_authority =
|
||||
self.pubkey_withdraw_withheld_authority.try_into()?;
|
||||
let pubkey_dest = self.pubkey_dest.try_into()?;
|
||||
let ciphertext_withdraw_withheld_authority =
|
||||
self.ciphertext_withdraw_withheld_authority.try_into()?;
|
||||
let ciphertext_dest = self.ciphertext_dest.try_into()?;
|
||||
let withdraw_withheld_authority_pubkey =
|
||||
self.withdraw_withheld_authority_pubkey.try_into()?;
|
||||
let destination_pubkey = self.destination_pubkey.try_into()?;
|
||||
let withdraw_withheld_authority_ciphertext =
|
||||
self.withdraw_withheld_authority_ciphertext.try_into()?;
|
||||
let destination_ciphertext = self.destination_ciphertext.try_into()?;
|
||||
|
||||
self.proof.verify(
|
||||
&pubkey_withdraw_withheld_authority,
|
||||
&pubkey_dest,
|
||||
&ciphertext_withdraw_withheld_authority,
|
||||
&ciphertext_dest,
|
||||
&withdraw_withheld_authority_pubkey,
|
||||
&destination_pubkey,
|
||||
&withdraw_withheld_authority_ciphertext,
|
||||
&destination_ciphertext,
|
||||
&mut transcript,
|
||||
)
|
||||
}
|
||||
|
@ -123,42 +123,42 @@ pub struct WithdrawWithheldTokensProof {
|
|||
#[cfg(not(target_arch = "bpf"))]
|
||||
impl WithdrawWithheldTokensProof {
|
||||
fn transcript_new(
|
||||
pubkey_withdraw_withheld_authority: &pod::ElGamalPubkey,
|
||||
pubkey_dest: &pod::ElGamalPubkey,
|
||||
ciphertext_withdraw_withheld_authority: &pod::ElGamalCiphertext,
|
||||
ciphertext_dest: &pod::ElGamalCiphertext,
|
||||
withdraw_withheld_authority_pubkey: &pod::ElGamalPubkey,
|
||||
destination_pubkey: &pod::ElGamalPubkey,
|
||||
withdraw_withheld_authority_ciphertext: &pod::ElGamalCiphertext,
|
||||
destination_ciphertext: &pod::ElGamalCiphertext,
|
||||
) -> Transcript {
|
||||
let mut transcript = Transcript::new(b"WithdrawWithheldTokensProof");
|
||||
|
||||
transcript.append_pubkey(
|
||||
b"withdraw-withheld-authority-pubkey",
|
||||
pubkey_withdraw_withheld_authority,
|
||||
withdraw_withheld_authority_pubkey,
|
||||
);
|
||||
transcript.append_pubkey(b"dest-pubkey", pubkey_dest);
|
||||
transcript.append_pubkey(b"dest-pubkey", destination_pubkey);
|
||||
|
||||
transcript.append_ciphertext(
|
||||
b"ciphertext-withdraw-withheld-authority",
|
||||
ciphertext_withdraw_withheld_authority,
|
||||
withdraw_withheld_authority_ciphertext,
|
||||
);
|
||||
transcript.append_ciphertext(b"ciphertext-dest", ciphertext_dest);
|
||||
transcript.append_ciphertext(b"ciphertext-dest", destination_ciphertext);
|
||||
|
||||
transcript
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
keypair_withdraw_withheld_authority: &ElGamalKeypair,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
ciphertext_withdraw_withheld_authority: &ElGamalCiphertext,
|
||||
withdraw_withheld_authority_keypair: &ElGamalKeypair,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
withdraw_withheld_authority_ciphertext: &ElGamalCiphertext,
|
||||
amount: u64,
|
||||
opening_dest: &PedersenOpening,
|
||||
destination_opening: &PedersenOpening,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
let equality_proof = CtxtCtxtEqualityProof::new(
|
||||
keypair_withdraw_withheld_authority,
|
||||
pubkey_dest,
|
||||
ciphertext_withdraw_withheld_authority,
|
||||
withdraw_withheld_authority_keypair,
|
||||
destination_pubkey,
|
||||
withdraw_withheld_authority_ciphertext,
|
||||
amount,
|
||||
opening_dest,
|
||||
destination_opening,
|
||||
transcript,
|
||||
);
|
||||
|
||||
|
@ -169,18 +169,18 @@ impl WithdrawWithheldTokensProof {
|
|||
|
||||
pub fn verify(
|
||||
&self,
|
||||
pubkey_source: &ElGamalPubkey,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
ciphertext_source: &ElGamalCiphertext,
|
||||
ciphertext_dest: &ElGamalCiphertext,
|
||||
source_pubkey: &ElGamalPubkey,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
source_ciphertext: &ElGamalCiphertext,
|
||||
destination_ciphertext: &ElGamalCiphertext,
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), ProofError> {
|
||||
let proof: CtxtCtxtEqualityProof = self.proof.try_into()?;
|
||||
proof.verify(
|
||||
pubkey_source,
|
||||
pubkey_dest,
|
||||
ciphertext_source,
|
||||
ciphertext_dest,
|
||||
source_pubkey,
|
||||
destination_pubkey,
|
||||
source_ciphertext,
|
||||
destination_ciphertext,
|
||||
transcript,
|
||||
)?;
|
||||
|
||||
|
@ -194,17 +194,17 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_close_account_correctness() {
|
||||
let keypair_withdraw_withheld_authority = ElGamalKeypair::new_rand();
|
||||
let keypair_dest = ElGamalKeypair::new_rand();
|
||||
let withdraw_withheld_authority_keypair = ElGamalKeypair::new_rand();
|
||||
let dest_keypair = ElGamalKeypair::new_rand();
|
||||
|
||||
let amount: u64 = 55;
|
||||
let ciphertext_withdraw_withheld_authority =
|
||||
keypair_withdraw_withheld_authority.public.encrypt(amount);
|
||||
let withdraw_withheld_authority_ciphertext =
|
||||
withdraw_withheld_authority_keypair.public.encrypt(amount);
|
||||
|
||||
let withdraw_withheld_tokens_data = WithdrawWithheldTokensData::new(
|
||||
&keypair_withdraw_withheld_authority,
|
||||
&keypair_dest.public,
|
||||
&ciphertext_withdraw_withheld_authority,
|
||||
&withdraw_withheld_authority_keypair,
|
||||
&dest_keypair.public,
|
||||
&withdraw_withheld_authority_ciphertext,
|
||||
amount,
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -59,14 +59,14 @@ impl CtxtCommEqualityProof {
|
|||
/// Note that the proof constructor does not take the actual Pedersen commitment as input; it
|
||||
/// takes the associated Pedersen opening instead.
|
||||
///
|
||||
/// * `elgamal_keypair` - The ElGamal keypair associated with the ciphertext to be proved
|
||||
/// * `ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `source_keypair` - The ElGamal keypair associated with the first to be proved
|
||||
/// * `source_ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `amount` - The message associated with the ElGamal ciphertext and Pedersen commitment
|
||||
/// * `opening` - The opening associated with the main Pedersen commitment to be proved
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn new(
|
||||
keypair_source: &ElGamalKeypair,
|
||||
ciphertext_source: &ElGamalCiphertext,
|
||||
source_keypair: &ElGamalKeypair,
|
||||
source_ciphertext: &ElGamalCiphertext,
|
||||
amount: u64,
|
||||
opening: &PedersenOpening,
|
||||
transcript: &mut Transcript,
|
||||
|
@ -74,10 +74,10 @@ impl CtxtCommEqualityProof {
|
|||
transcript.equality_proof_domain_sep();
|
||||
|
||||
// extract the relevant scalar and Ristretto points from the inputs
|
||||
let P_source = keypair_source.public.get_point();
|
||||
let D_source = ciphertext_source.handle.get_point();
|
||||
let P_source = source_keypair.public.get_point();
|
||||
let D_source = source_ciphertext.handle.get_point();
|
||||
|
||||
let s = keypair_source.secret.get_scalar();
|
||||
let s = source_keypair.secret.get_scalar();
|
||||
let x = Scalar::from(amount);
|
||||
let r = opening.get_scalar();
|
||||
|
||||
|
@ -121,24 +121,24 @@ impl CtxtCommEqualityProof {
|
|||
|
||||
/// Equality proof verifier. TODO: wrt commitment
|
||||
///
|
||||
/// * `elgamal_pubkey` - The ElGamal pubkey associated with the ciphertext to be proved
|
||||
/// * `ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `commitment` - The main Pedersen commitment to be proved
|
||||
/// * `source_pubkey` - The ElGamal pubkey associated with the ciphertext to be proved
|
||||
/// * `source_ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `destination_commitment` - The main Pedersen commitment to be proved
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn verify(
|
||||
self,
|
||||
pubkey_source: &ElGamalPubkey,
|
||||
ciphertext_source: &ElGamalCiphertext,
|
||||
commitment_dest: &PedersenCommitment,
|
||||
source_pubkey: &ElGamalPubkey,
|
||||
source_ciphertext: &ElGamalCiphertext,
|
||||
destination_commitment: &PedersenCommitment,
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), EqualityProofError> {
|
||||
transcript.equality_proof_domain_sep();
|
||||
|
||||
// extract the relevant scalar and Ristretto points from the inputs
|
||||
let P_source = pubkey_source.get_point();
|
||||
let C_source = ciphertext_source.commitment.get_point();
|
||||
let D_source = ciphertext_source.handle.get_point();
|
||||
let C_dest = commitment_dest.get_point();
|
||||
let P_source = source_pubkey.get_point();
|
||||
let C_source = source_ciphertext.commitment.get_point();
|
||||
let D_source = source_ciphertext.handle.get_point();
|
||||
let C_destination = destination_commitment.get_point();
|
||||
|
||||
// include Y_0, Y_1, Y_2 to transcript and extract challenges
|
||||
transcript.validate_and_append_point(b"Y_0", &self.Y_0)?;
|
||||
|
@ -172,17 +172,17 @@ impl CtxtCommEqualityProof {
|
|||
&ww_negated, // -ww
|
||||
],
|
||||
vec![
|
||||
P_source, // P_source
|
||||
&(*H), // H
|
||||
&Y_0, // Y_0
|
||||
&(*G), // G
|
||||
D_source, // D_source
|
||||
C_source, // C_source
|
||||
&Y_1, // Y_1
|
||||
&(*G), // G
|
||||
&(*H), // H
|
||||
C_dest, // C_dest
|
||||
&Y_2, // Y_2
|
||||
P_source, // P_source
|
||||
&(*H), // H
|
||||
&Y_0, // Y_0
|
||||
&(*G), // G
|
||||
D_source, // D_source
|
||||
C_source, // C_source
|
||||
&Y_1, // Y_1
|
||||
&(*G), // G
|
||||
&(*H), // H
|
||||
C_destination, // C_destination
|
||||
&Y_2, // Y_2
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -256,29 +256,30 @@ impl CtxtCtxtEqualityProof {
|
|||
/// Note that the proof constructor does not take the actual Pedersen commitment as input; it
|
||||
/// takes the associated Pedersen opening instead.
|
||||
///
|
||||
/// * `elgamal_keypair` - The ElGamal keypair associated with the ciphertext to be proved
|
||||
/// * `ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `source_keypair` - The ElGamal keypair associated with the first ciphertext to be proved
|
||||
/// * `destination_pubkey` - The ElGamal pubkey associated with the second ElGamal ciphertext
|
||||
/// * `source_ciphertext` - The first ElGamal ciphertext
|
||||
/// * `amount` - The message associated with the ElGamal ciphertext and Pedersen commitment
|
||||
/// * `opening` - The opening associated with the main Pedersen commitment to be proved
|
||||
/// * `destination_opening` - The opening associated with the second ElGamal ciphertext
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn new(
|
||||
keypair_source: &ElGamalKeypair,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
ciphertext_source: &ElGamalCiphertext,
|
||||
source_keypair: &ElGamalKeypair,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
source_ciphertext: &ElGamalCiphertext,
|
||||
amount: u64,
|
||||
opening_dest: &PedersenOpening,
|
||||
destination_opening: &PedersenOpening,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
transcript.equality_proof_domain_sep();
|
||||
|
||||
// extract the relevant scalar and Ristretto points from the inputs
|
||||
let P_source = keypair_source.public.get_point();
|
||||
let D_source = ciphertext_source.handle.get_point();
|
||||
let P_dest = pubkey_dest.get_point();
|
||||
let P_source = source_keypair.public.get_point();
|
||||
let D_source = source_ciphertext.handle.get_point();
|
||||
let P_destination = destination_pubkey.get_point();
|
||||
|
||||
let s = keypair_source.secret.get_scalar();
|
||||
let s = source_keypair.secret.get_scalar();
|
||||
let x = Scalar::from(amount);
|
||||
let r = opening_dest.get_scalar();
|
||||
let r = destination_opening.get_scalar();
|
||||
|
||||
// generate random masking factors that also serves as nonces
|
||||
let mut y_s = Scalar::random(&mut OsRng);
|
||||
|
@ -289,7 +290,7 @@ impl CtxtCtxtEqualityProof {
|
|||
let Y_1 =
|
||||
RistrettoPoint::multiscalar_mul(vec![&y_x, &y_s], vec![&(*G), D_source]).compress();
|
||||
let Y_2 = RistrettoPoint::multiscalar_mul(vec![&y_x, &y_r], vec![&(*G), &(*H)]).compress();
|
||||
let Y_3 = (&y_r * P_dest).compress();
|
||||
let Y_3 = (&y_r * P_destination).compress();
|
||||
|
||||
// record masking factors in the transcript
|
||||
transcript.append_point(b"Y_0", &Y_0);
|
||||
|
@ -321,30 +322,31 @@ impl CtxtCtxtEqualityProof {
|
|||
}
|
||||
}
|
||||
|
||||
/// Equality proof verifier. TODO: wrt commitment
|
||||
/// Equality proof verifier.
|
||||
///
|
||||
/// * `elgamal_pubkey` - The ElGamal pubkey associated with the ciphertext to be proved
|
||||
/// * `ciphertext` - The main ElGamal ciphertext to be proved
|
||||
/// * `commitment` - The main Pedersen commitment to be proved
|
||||
/// * `source_pubkey` - The ElGamal pubkey associated with the first ciphertext to be proved
|
||||
/// * `destination_pubkey` - The ElGamal pubkey associated with the second ciphertext to be proved
|
||||
/// * `source_ciphertext` - The first ElGamal ciphertext to be proved
|
||||
/// * `destination_ciphertext` - The second ElGamal ciphertext to be proved
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn verify(
|
||||
self,
|
||||
pubkey_source: &ElGamalPubkey,
|
||||
pubkey_dest: &ElGamalPubkey,
|
||||
ciphertext_source: &ElGamalCiphertext,
|
||||
ciphertext_dest: &ElGamalCiphertext,
|
||||
source_pubkey: &ElGamalPubkey,
|
||||
destination_pubkey: &ElGamalPubkey,
|
||||
source_ciphertext: &ElGamalCiphertext,
|
||||
destination_ciphertext: &ElGamalCiphertext,
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), EqualityProofError> {
|
||||
transcript.equality_proof_domain_sep();
|
||||
|
||||
// extract the relevant scalar and Ristretto points from the inputs
|
||||
let P_source = pubkey_source.get_point();
|
||||
let C_source = ciphertext_source.commitment.get_point();
|
||||
let D_source = ciphertext_source.handle.get_point();
|
||||
let P_source = source_pubkey.get_point();
|
||||
let C_source = source_ciphertext.commitment.get_point();
|
||||
let D_source = source_ciphertext.handle.get_point();
|
||||
|
||||
let P_dest = pubkey_dest.get_point();
|
||||
let C_dest = ciphertext_dest.commitment.get_point();
|
||||
let D_dest = ciphertext_dest.handle.get_point();
|
||||
let P_destination = destination_pubkey.get_point();
|
||||
let C_destination = destination_ciphertext.commitment.get_point();
|
||||
let D_destination = destination_ciphertext.handle.get_point();
|
||||
|
||||
// include Y_0, Y_1, Y_2 to transcript and extract challenges
|
||||
transcript.validate_and_append_point(b"Y_0", &self.Y_0)?;
|
||||
|
@ -385,20 +387,20 @@ impl CtxtCtxtEqualityProof {
|
|||
&www_negated,
|
||||
],
|
||||
vec![
|
||||
P_source, // P_source
|
||||
&(*H), // H
|
||||
&Y_0, // Y_0
|
||||
&(*G), // G
|
||||
D_source, // D_source
|
||||
C_source, // C_source
|
||||
&Y_1, // Y_1
|
||||
&(*G), // G
|
||||
&(*H), // H
|
||||
C_dest, // C_dest
|
||||
&Y_2, // Y_2
|
||||
P_dest, // P_dest
|
||||
D_dest, // D_dest
|
||||
&Y_3, // Y_3
|
||||
P_source, // P_source
|
||||
&(*H), // H
|
||||
&Y_0, // Y_0
|
||||
&(*G), // G
|
||||
D_source, // D_source
|
||||
C_source, // C_source
|
||||
&Y_1, // Y_1
|
||||
&(*G), // G
|
||||
&(*H), // H
|
||||
C_destination, // C_destination
|
||||
&Y_2, // Y_2
|
||||
P_destination, // P_destination
|
||||
D_destination, // D_destination
|
||||
&Y_3, // Y_3
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -456,57 +458,57 @@ mod test {
|
|||
#[test]
|
||||
fn test_ciphertext_commitment_equality_proof_correctness() {
|
||||
// success case
|
||||
let keypair_source = ElGamalKeypair::new_rand();
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
let message: u64 = 55;
|
||||
|
||||
let ciphertext_source = keypair_source.public.encrypt(message);
|
||||
let (commitment_dest, opening_dest) = Pedersen::new(message);
|
||||
let source_ciphertext = source_keypair.public.encrypt(message);
|
||||
let (destination_commitment, destination_opening) = Pedersen::new(message);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&keypair_source,
|
||||
&ciphertext_source,
|
||||
&source_keypair,
|
||||
&source_ciphertext,
|
||||
message,
|
||||
&opening_dest,
|
||||
&mut transcript_prover,
|
||||
&destination_opening,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&keypair_source.public,
|
||||
&ciphertext_source,
|
||||
&commitment_dest,
|
||||
&mut transcript_verifier
|
||||
&source_keypair.public,
|
||||
&source_ciphertext,
|
||||
&destination_commitment,
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// fail case: encrypted and committed messages are different
|
||||
let keypair_source = ElGamalKeypair::new_rand();
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
let encrypted_message: u64 = 55;
|
||||
let committed_message: u64 = 77;
|
||||
|
||||
let ciphertext_source = keypair_source.public.encrypt(encrypted_message);
|
||||
let (commitment_dest, opening_dest) = Pedersen::new(committed_message);
|
||||
let source_ciphertext = source_keypair.public.encrypt(encrypted_message);
|
||||
let (destination_commitment, destination_opening) = Pedersen::new(committed_message);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&keypair_source,
|
||||
&ciphertext_source,
|
||||
&source_keypair,
|
||||
&source_ciphertext,
|
||||
message,
|
||||
&opening_dest,
|
||||
&mut transcript_prover,
|
||||
&destination_opening,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&keypair_source.public,
|
||||
&ciphertext_source,
|
||||
&commitment_dest,
|
||||
&mut transcript_verifier
|
||||
&source_keypair.public,
|
||||
&source_ciphertext,
|
||||
&destination_commitment,
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
@ -523,15 +525,15 @@ mod test {
|
|||
let ciphertext = elgamal_keypair.public.encrypt(message);
|
||||
let (commitment, opening) = Pedersen::new(message);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&elgamal_keypair,
|
||||
&ciphertext,
|
||||
message,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
|
@ -539,7 +541,7 @@ mod test {
|
|||
&elgamal_keypair.public,
|
||||
&ciphertext,
|
||||
&commitment,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
|
||||
|
@ -552,15 +554,15 @@ mod test {
|
|||
let commitment = PedersenCommitment::from_bytes(&[0u8; 32]).unwrap();
|
||||
let opening = PedersenOpening::from_bytes(&[0u8; 32]).unwrap();
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&elgamal_keypair,
|
||||
&ciphertext,
|
||||
message,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
|
@ -568,7 +570,7 @@ mod test {
|
|||
&elgamal_keypair.public,
|
||||
&ciphertext,
|
||||
&commitment,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
|
@ -581,15 +583,15 @@ mod test {
|
|||
let commitment = PedersenCommitment::from_bytes(&[0u8; 32]).unwrap();
|
||||
let opening = PedersenOpening::from_bytes(&[0u8; 32]).unwrap();
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&elgamal_keypair,
|
||||
&ciphertext,
|
||||
message,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
|
@ -597,7 +599,7 @@ mod test {
|
|||
&elgamal_keypair.public,
|
||||
&ciphertext,
|
||||
&commitment,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
|
@ -609,15 +611,15 @@ mod test {
|
|||
let ciphertext = ElGamalCiphertext::from_bytes(&[0u8; 64]).unwrap();
|
||||
let (commitment, opening) = Pedersen::new(message);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCommEqualityProof::new(
|
||||
&elgamal_keypair,
|
||||
&ciphertext,
|
||||
message,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
|
@ -625,7 +627,7 @@ mod test {
|
|||
&elgamal_keypair.public,
|
||||
&ciphertext,
|
||||
&commitment,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
@ -633,67 +635,69 @@ mod test {
|
|||
#[test]
|
||||
fn test_ciphertext_ciphertext_equality_proof_correctness() {
|
||||
// success case
|
||||
let keypair_source = ElGamalKeypair::new_rand();
|
||||
let keypair_dest = ElGamalKeypair::new_rand();
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
let destination_keypair = ElGamalKeypair::new_rand();
|
||||
let message: u64 = 55;
|
||||
|
||||
let ciphertext_source = keypair_source.public.encrypt(message);
|
||||
let source_ciphertext = source_keypair.public.encrypt(message);
|
||||
|
||||
let opening_dest = PedersenOpening::new_rand();
|
||||
let ciphertext_dest = keypair_dest.public.encrypt_with(message, &opening_dest);
|
||||
let destination_opening = PedersenOpening::new_rand();
|
||||
let destination_ciphertext = destination_keypair
|
||||
.public
|
||||
.encrypt_with(message, &destination_opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCtxtEqualityProof::new(
|
||||
&keypair_source,
|
||||
&keypair_dest.public,
|
||||
&ciphertext_source,
|
||||
&source_keypair,
|
||||
&destination_keypair.public,
|
||||
&source_ciphertext,
|
||||
message,
|
||||
&opening_dest,
|
||||
&mut transcript_prover,
|
||||
&destination_opening,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&keypair_source.public,
|
||||
&keypair_dest.public,
|
||||
&ciphertext_source,
|
||||
&ciphertext_dest,
|
||||
&mut transcript_verifier
|
||||
&source_keypair.public,
|
||||
&destination_keypair.public,
|
||||
&source_ciphertext,
|
||||
&destination_ciphertext,
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// fail case: encrypted and committed messages are different
|
||||
let message_source: u64 = 55;
|
||||
let message_dest: u64 = 77;
|
||||
let source_message: u64 = 55;
|
||||
let destination_message: u64 = 77;
|
||||
|
||||
let ciphertext_source = keypair_source.public.encrypt(message_source);
|
||||
let source_ciphertext = source_keypair.public.encrypt(source_message);
|
||||
|
||||
let opening_dest = PedersenOpening::new_rand();
|
||||
let ciphertext_dest = keypair_dest
|
||||
let destination_opening = PedersenOpening::new_rand();
|
||||
let destination_ciphertext = destination_keypair
|
||||
.public
|
||||
.encrypt_with(message_dest, &opening_dest);
|
||||
.encrypt_with(destination_message, &destination_opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = CtxtCtxtEqualityProof::new(
|
||||
&keypair_source,
|
||||
&keypair_dest.public,
|
||||
&ciphertext_source,
|
||||
&source_keypair,
|
||||
&destination_keypair.public,
|
||||
&source_ciphertext,
|
||||
message,
|
||||
&opening_dest,
|
||||
&mut transcript_prover,
|
||||
&destination_opening,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&keypair_source.public,
|
||||
&keypair_dest.public,
|
||||
&ciphertext_source,
|
||||
&ciphertext_dest,
|
||||
&mut transcript_verifier
|
||||
&source_keypair.public,
|
||||
&destination_keypair.public,
|
||||
&source_ciphertext,
|
||||
&destination_ciphertext,
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
|
|
@ -40,18 +40,18 @@ impl FeeSigmaProof {
|
|||
/// Creates a fee sigma proof assuming that the committed fee is greater than the maximum fee
|
||||
/// bound.
|
||||
///
|
||||
/// * `(fee_amount, commitment_fee, opening_fee)` - The amount, Pedersen commitment, and
|
||||
/// * `(fee_amount, fee_commitment, fee_opening)` - The amount, Pedersen commitment, and
|
||||
/// opening of the transfer fee
|
||||
/// * `(delta_fee, commitment_delta, opening_delta)` - The amount, Pedersen commitment, and
|
||||
/// * `(delta_fee, delta_commitment, delta_opening)` - The amount, Pedersen commitment, and
|
||||
/// opening of the "real" delta amount
|
||||
/// * `(commitment_claimed, opening_claimed)` - The Pedersen commitment and opening of the
|
||||
/// * `(claimed_commitment, claimed_opening)` - The Pedersen commitment and opening of the
|
||||
/// "claimed" delta amount
|
||||
/// * `max_fee` - The maximum fee bound
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn new(
|
||||
(fee_amount, commitment_fee, opening_fee): (u64, &PedersenCommitment, &PedersenOpening),
|
||||
(delta_fee, commitment_delta, opening_delta): (u64, &PedersenCommitment, &PedersenOpening),
|
||||
(commitment_claimed, opening_claimed): (&PedersenCommitment, &PedersenOpening),
|
||||
(fee_amount, fee_commitment, fee_opening): (u64, &PedersenCommitment, &PedersenOpening),
|
||||
(delta_fee, delta_commitment, delta_opening): (u64, &PedersenCommitment, &PedersenOpening),
|
||||
(claimed_commitment, claimed_opening): (&PedersenCommitment, &PedersenOpening),
|
||||
max_fee: u64,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
|
@ -60,16 +60,16 @@ impl FeeSigmaProof {
|
|||
|
||||
// compute proof for both cases `fee_amount' >= `max_fee` and `fee_amount` < `max_fee`
|
||||
let proof_fee_above_max = Self::create_proof_fee_above_max(
|
||||
opening_fee,
|
||||
commitment_delta,
|
||||
commitment_claimed,
|
||||
fee_opening,
|
||||
delta_commitment,
|
||||
claimed_commitment,
|
||||
&mut transcript_fee_above_max,
|
||||
);
|
||||
|
||||
let proof_fee_below_max = Self::create_proof_fee_below_max(
|
||||
commitment_fee,
|
||||
(delta_fee, opening_delta),
|
||||
opening_claimed,
|
||||
fee_commitment,
|
||||
(delta_fee, delta_opening),
|
||||
claimed_opening,
|
||||
max_fee,
|
||||
&mut transcript_fee_below_max,
|
||||
);
|
||||
|
@ -100,19 +100,19 @@ impl FeeSigmaProof {
|
|||
/// Creates a fee sigma proof assuming that the committed fee is greater than the maximum fee
|
||||
/// bound.
|
||||
///
|
||||
/// * `opening_fee` - The opening of the Pedersen commitment of the transfer fee
|
||||
/// * `commitment_delta` - The Pedersen commitment of the "real" delta value
|
||||
/// * `commitment_claimed` - The Pedersen commitment of the "claimed" delta value
|
||||
/// * `fee_opening` - The opening of the Pedersen commitment of the transfer fee
|
||||
/// * `delta_commitment` - The Pedersen commitment of the "real" delta value
|
||||
/// * `claimed_commitment` - The Pedersen commitment of the "claimed" delta value
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
fn create_proof_fee_above_max(
|
||||
opening_fee: &PedersenOpening,
|
||||
commitment_delta: &PedersenCommitment,
|
||||
commitment_claimed: &PedersenCommitment,
|
||||
fee_opening: &PedersenOpening,
|
||||
delta_commitment: &PedersenCommitment,
|
||||
claimed_commitment: &PedersenCommitment,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
// simulate equality proof
|
||||
let C_delta = commitment_delta.get_point();
|
||||
let C_claimed = commitment_claimed.get_point();
|
||||
let C_delta = delta_commitment.get_point();
|
||||
let C_claimed = claimed_commitment.get_point();
|
||||
|
||||
let z_x = Scalar::random(&mut OsRng);
|
||||
let z_delta = Scalar::random(&mut OsRng);
|
||||
|
@ -140,7 +140,7 @@ impl FeeSigmaProof {
|
|||
};
|
||||
|
||||
// generate max proof
|
||||
let r_fee = opening_fee.get_scalar();
|
||||
let r_fee = fee_opening.get_scalar();
|
||||
|
||||
let y_max_proof = Scalar::random(&mut OsRng);
|
||||
let Y_max_proof = (y_max_proof * &(*H)).compress();
|
||||
|
@ -171,22 +171,22 @@ impl FeeSigmaProof {
|
|||
/// Creates a fee sigma proof assuming that the committed fee is less than the maximum fee
|
||||
/// bound.
|
||||
///
|
||||
/// * `commitment_fee` - The Pedersen commitment of the transfer fee
|
||||
/// * `(delta_fee, opening_delta)` - The Pedersen commitment and opening of the "real" delta
|
||||
/// * `fee_commitment` - The Pedersen commitment of the transfer fee
|
||||
/// * `(delta_fee, delta_opening)` - The Pedersen commitment and opening of the "real" delta
|
||||
/// value
|
||||
/// * `opening_claimed` - The opening of the Pedersen commitment of the "claimed" delta value
|
||||
/// * `claimed_opening` - The opening of the Pedersen commitment of the "claimed" delta value
|
||||
/// * `max_fee` - The maximum fee bound
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
fn create_proof_fee_below_max(
|
||||
commitment_fee: &PedersenCommitment,
|
||||
(delta_fee, opening_delta): (u64, &PedersenOpening),
|
||||
opening_claimed: &PedersenOpening,
|
||||
fee_commitment: &PedersenCommitment,
|
||||
(delta_fee, delta_opening): (u64, &PedersenOpening),
|
||||
claimed_opening: &PedersenOpening,
|
||||
max_fee: u64,
|
||||
transcript: &mut Transcript,
|
||||
) -> Self {
|
||||
// simulate max proof
|
||||
let m = Scalar::from(max_fee);
|
||||
let C_fee = commitment_fee.get_point();
|
||||
let C_fee = fee_commitment.get_point();
|
||||
|
||||
let z_max_proof = Scalar::random(&mut OsRng);
|
||||
let c_max_proof = Scalar::random(&mut OsRng); // random challenge
|
||||
|
@ -207,8 +207,8 @@ impl FeeSigmaProof {
|
|||
// generate equality proof
|
||||
let x = Scalar::from(delta_fee);
|
||||
|
||||
let r_delta = opening_delta.get_scalar();
|
||||
let r_claimed = opening_claimed.get_scalar();
|
||||
let r_delta = delta_opening.get_scalar();
|
||||
let r_claimed = claimed_opening.get_scalar();
|
||||
|
||||
let y_x = Scalar::random(&mut OsRng);
|
||||
let y_delta = Scalar::random(&mut OsRng);
|
||||
|
@ -248,25 +248,25 @@ impl FeeSigmaProof {
|
|||
|
||||
/// Fee sigma proof verifier.
|
||||
///
|
||||
/// * `commitment_fee` - The Pedersen commitment of the transfer fee
|
||||
/// * `commitment_delta` - The Pedersen commitment of the "real" delta value
|
||||
/// * `commitment_claimed` - The Pedersen commitment of the "claimed" delta value
|
||||
/// * `fee_commitment` - The Pedersen commitment of the transfer fee
|
||||
/// * `delta_commitment` - The Pedersen commitment of the "real" delta value
|
||||
/// * `claimed_commitment` - The Pedersen commitment of the "claimed" delta value
|
||||
/// * `max_fee` - The maximum fee bound
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn verify(
|
||||
self,
|
||||
commitment_fee: &PedersenCommitment,
|
||||
commitment_delta: &PedersenCommitment,
|
||||
commitment_claimed: &PedersenCommitment,
|
||||
fee_commitment: &PedersenCommitment,
|
||||
delta_commitment: &PedersenCommitment,
|
||||
claimed_commitment: &PedersenCommitment,
|
||||
max_fee: u64,
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), FeeSigmaProofError> {
|
||||
// extract the relevant scalar and Ristretto points from the input
|
||||
let m = Scalar::from(max_fee);
|
||||
|
||||
let C_max = commitment_fee.get_point();
|
||||
let C_delta = commitment_delta.get_point();
|
||||
let C_claimed = commitment_claimed.get_point();
|
||||
let C_max = fee_commitment.get_point();
|
||||
let C_delta = delta_commitment.get_point();
|
||||
let C_claimed = claimed_commitment.get_point();
|
||||
|
||||
transcript.validate_and_append_point(b"Y_max_proof", &self.fee_max_proof.Y_max_proof)?;
|
||||
transcript.validate_and_append_point(b"Y_delta", &self.fee_equality_proof.Y_delta)?;
|
||||
|
@ -455,39 +455,39 @@ mod test {
|
|||
let transfer_amount: u64 = 55;
|
||||
let max_fee: u64 = 3;
|
||||
|
||||
let rate_fee: u16 = 555; // 5.55%
|
||||
let amount_fee: u64 = 4;
|
||||
let fee_rate: u16 = 555; // 5.55%
|
||||
let fee_amount: u64 = 4;
|
||||
let delta: u64 = 9475; // 4*10000 - 55*555
|
||||
|
||||
let (commitment_transfer, opening_transfer) = Pedersen::new(transfer_amount);
|
||||
let (commitment_fee, opening_fee) = Pedersen::new(max_fee);
|
||||
let (transfer_commitment, transfer_opening) = Pedersen::new(transfer_amount);
|
||||
let (fee_commitment, fee_opening) = Pedersen::new(max_fee);
|
||||
|
||||
let scalar_rate = Scalar::from(rate_fee);
|
||||
let commitment_delta =
|
||||
&commitment_fee * &Scalar::from(10000_u64) - &commitment_transfer * &scalar_rate;
|
||||
let opening_delta =
|
||||
&opening_fee * &Scalar::from(10000_u64) - &opening_transfer * &scalar_rate;
|
||||
let scalar_rate = Scalar::from(fee_rate);
|
||||
let delta_commitment =
|
||||
&fee_commitment * &Scalar::from(10000_u64) - &transfer_commitment * &scalar_rate;
|
||||
let delta_opening =
|
||||
&fee_opening * &Scalar::from(10000_u64) - &transfer_opening * &scalar_rate;
|
||||
|
||||
let (commitment_claimed, opening_claimed) = Pedersen::new(0_u64);
|
||||
let (claimed_commitment, claimed_opening) = Pedersen::new(0_u64);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let proof = FeeSigmaProof::new(
|
||||
(amount_fee, &commitment_fee, &opening_fee),
|
||||
(delta, &commitment_delta, &opening_delta),
|
||||
(&commitment_claimed, &opening_claimed),
|
||||
(fee_amount, &fee_commitment, &fee_opening),
|
||||
(delta, &delta_commitment, &delta_opening),
|
||||
(&claimed_commitment, &claimed_opening),
|
||||
max_fee,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment_fee,
|
||||
&commitment_delta,
|
||||
&commitment_claimed,
|
||||
&fee_commitment,
|
||||
&delta_commitment,
|
||||
&claimed_commitment,
|
||||
max_fee,
|
||||
&mut transcript_verifier,
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
@ -497,44 +497,44 @@ mod test {
|
|||
let transfer_amount: u64 = 55;
|
||||
let max_fee: u64 = 77;
|
||||
|
||||
let rate_fee: u16 = 555; // 5.55%
|
||||
let amount_fee: u64 = 4;
|
||||
let fee_rate: u16 = 555; // 5.55%
|
||||
let fee_amount: u64 = 4;
|
||||
let delta: u64 = 9475; // 4*10000 - 55*555
|
||||
|
||||
let (commitment_transfer, opening_transfer) = Pedersen::new(transfer_amount);
|
||||
let (commitment_fee, opening_fee) = Pedersen::new(amount_fee);
|
||||
let (transfer_commitment, transfer_opening) = Pedersen::new(transfer_amount);
|
||||
let (fee_commitment, fee_opening) = Pedersen::new(fee_amount);
|
||||
|
||||
let scalar_rate = Scalar::from(rate_fee);
|
||||
let commitment_delta =
|
||||
&commitment_fee * &Scalar::from(10000_u64) - &commitment_transfer * &scalar_rate;
|
||||
let opening_delta =
|
||||
&opening_fee * &Scalar::from(10000_u64) - &opening_transfer * &scalar_rate;
|
||||
let scalar_rate = Scalar::from(fee_rate);
|
||||
let delta_commitment =
|
||||
&fee_commitment * &Scalar::from(10000_u64) - &transfer_commitment * &scalar_rate;
|
||||
let delta_opening =
|
||||
&fee_opening * &Scalar::from(10000_u64) - &transfer_opening * &scalar_rate;
|
||||
|
||||
let (commitment_claimed, opening_claimed) = Pedersen::new(delta);
|
||||
let (claimed_commitment, claimed_opening) = Pedersen::new(delta);
|
||||
|
||||
assert_eq!(
|
||||
commitment_delta.get_point() - opening_delta.get_scalar() * &(*H),
|
||||
commitment_claimed.get_point() - opening_claimed.get_scalar() * &(*H)
|
||||
delta_commitment.get_point() - delta_opening.get_scalar() * &(*H),
|
||||
claimed_commitment.get_point() - claimed_opening.get_scalar() * &(*H)
|
||||
);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let proof = FeeSigmaProof::new(
|
||||
(amount_fee, &commitment_fee, &opening_fee),
|
||||
(delta, &commitment_delta, &opening_delta),
|
||||
(&commitment_claimed, &opening_claimed),
|
||||
(fee_amount, &fee_commitment, &fee_opening),
|
||||
(delta, &delta_commitment, &delta_opening),
|
||||
(&claimed_commitment, &claimed_opening),
|
||||
max_fee,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment_fee,
|
||||
&commitment_delta,
|
||||
&commitment_claimed,
|
||||
&fee_commitment,
|
||||
&delta_commitment,
|
||||
&claimed_commitment,
|
||||
max_fee,
|
||||
&mut transcript_verifier,
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
@ -544,39 +544,39 @@ mod test {
|
|||
let transfer_amount: u64 = 100;
|
||||
let max_fee: u64 = 3;
|
||||
|
||||
let rate_fee: u16 = 100; // 1.00%
|
||||
let amount_fee: u64 = 1;
|
||||
let fee_rate: u16 = 100; // 1.00%
|
||||
let fee_amount: u64 = 1;
|
||||
let delta: u64 = 0; // 1*10000 - 100*100
|
||||
|
||||
let (commitment_transfer, opening_transfer) = Pedersen::new(transfer_amount);
|
||||
let (commitment_fee, opening_fee) = Pedersen::new(amount_fee);
|
||||
let (transfer_commitment, transfer_opening) = Pedersen::new(transfer_amount);
|
||||
let (fee_commitment, fee_opening) = Pedersen::new(fee_amount);
|
||||
|
||||
let scalar_rate = Scalar::from(rate_fee);
|
||||
let commitment_delta =
|
||||
&(&commitment_fee * &Scalar::from(10000_u64)) - &(&commitment_transfer * &scalar_rate);
|
||||
let opening_delta =
|
||||
&(&opening_fee * &Scalar::from(10000_u64)) - &(&opening_transfer * &scalar_rate);
|
||||
let scalar_rate = Scalar::from(fee_rate);
|
||||
let delta_commitment =
|
||||
&(&fee_commitment * &Scalar::from(10000_u64)) - &(&transfer_commitment * &scalar_rate);
|
||||
let delta_opening =
|
||||
&(&fee_opening * &Scalar::from(10000_u64)) - &(&transfer_opening * &scalar_rate);
|
||||
|
||||
let (commitment_claimed, opening_claimed) = Pedersen::new(delta);
|
||||
let (claimed_commitment, claimed_opening) = Pedersen::new(delta);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let proof = FeeSigmaProof::new(
|
||||
(amount_fee, &commitment_fee, &opening_fee),
|
||||
(delta, &commitment_delta, &opening_delta),
|
||||
(&commitment_claimed, &opening_claimed),
|
||||
(fee_amount, &fee_commitment, &fee_opening),
|
||||
(delta, &delta_commitment, &delta_opening),
|
||||
(&claimed_commitment, &claimed_opening),
|
||||
max_fee,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment_fee,
|
||||
&commitment_delta,
|
||||
&commitment_claimed,
|
||||
&fee_commitment,
|
||||
&delta_commitment,
|
||||
&claimed_commitment,
|
||||
max_fee,
|
||||
&mut transcript_verifier,
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
|
|
@ -56,13 +56,13 @@ impl ValidityProof {
|
|||
/// Note that the proof constructor does not take the actual Pedersen commitment or decryption
|
||||
/// handles as input; it only takes the associated Pedersen opening instead.
|
||||
///
|
||||
/// * `(pubkey_dest, pubkey_auditor)` - The ElGamal public keys associated with the decryption
|
||||
/// * `(destination_pubkey, auditor_pubkey)` - The ElGamal public keys associated with the decryption
|
||||
/// handles
|
||||
/// * `amount` - The committed message in the commitment
|
||||
/// * `opening` - The opening associated with the Pedersen commitment
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn new<T: Into<Scalar>>(
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey), // TODO: rename pubkey_auditor
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey), // TODO: rename auditor_pubkey
|
||||
amount: T,
|
||||
opening: &PedersenOpening,
|
||||
transcript: &mut Transcript,
|
||||
|
@ -70,8 +70,8 @@ impl ValidityProof {
|
|||
transcript.validity_proof_domain_sep();
|
||||
|
||||
// extract the relevant scalar and Ristretto points from the inputs
|
||||
let P_dest = pubkey_dest.get_point();
|
||||
let P_auditor = pubkey_auditor.get_point();
|
||||
let P_dest = destination_pubkey.get_point();
|
||||
let P_auditor = auditor_pubkey.get_point();
|
||||
|
||||
let x = amount.into();
|
||||
let r = opening.get_scalar();
|
||||
|
@ -111,15 +111,15 @@ impl ValidityProof {
|
|||
/// The ciphertext validity proof verifier.
|
||||
///
|
||||
/// * `commitment` - The Pedersen commitment
|
||||
/// * `(pubkey_dest, pubkey_auditor)` - The ElGamal pubkeys associated with the decryption
|
||||
/// * `(destination_pubkey, auditor_pubkey)` - The ElGamal pubkeys associated with the decryption
|
||||
/// handles
|
||||
/// * `(handle_dest, handle_audtior)` - The decryption handles
|
||||
/// * `(destination_handle, auditor_handle)` - The decryption handles
|
||||
/// * `transcript` - The transcript that does the bookkeeping for the Fiat-Shamir heuristic
|
||||
pub fn verify(
|
||||
self,
|
||||
commitment: &PedersenCommitment,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(handle_dest, handle_auditor): (&DecryptHandle, &DecryptHandle),
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(destination_handle, auditor_handle): (&DecryptHandle, &DecryptHandle),
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), ValidityProofError> {
|
||||
transcript.validity_proof_domain_sep();
|
||||
|
@ -141,12 +141,12 @@ impl ValidityProof {
|
|||
let Y_1 = self.Y_1.decompress().ok_or(ValidityProofError::Format)?;
|
||||
let Y_2 = self.Y_2.decompress().ok_or(ValidityProofError::Format)?;
|
||||
|
||||
let P_dest = pubkey_dest.get_point();
|
||||
let P_auditor = pubkey_auditor.get_point();
|
||||
let P_dest = destination_pubkey.get_point();
|
||||
let P_auditor = auditor_pubkey.get_point();
|
||||
|
||||
let C = commitment.get_point();
|
||||
let D_dest = handle_dest.get_point();
|
||||
let D_auditor = handle_auditor.get_point();
|
||||
let D_dest = destination_handle.get_point();
|
||||
let D_auditor = auditor_handle.get_point();
|
||||
|
||||
let check = RistrettoPoint::vartime_multiscalar_mul(
|
||||
vec![
|
||||
|
@ -217,9 +217,9 @@ impl ValidityProof {
|
|||
///
|
||||
/// An aggregated ciphertext validity proof certifies the validity of two instances of a standard
|
||||
/// ciphertext validity proof. An instance of a standard validity proof consist of one ciphertext
|
||||
/// and two decryption handles `(commitment, handle_dest, handle_auditor)`. An instance of an
|
||||
/// aggregated ciphertext validity proof is a pair `(commitment_0, handle_dest_0,
|
||||
/// handle_auditor_0)` and `(commitment_1, handle_dest_1, handle_auditor_1)`. The proof certifies
|
||||
/// and two decryption handles `(commitment, destination_handle, auditor_handle)`. An instance of an
|
||||
/// aggregated ciphertext validity proof is a pair `(commitment_0, destination_handle_0,
|
||||
/// auditor_handle_0)` and `(commitment_1, destination_handle_1, auditor_handle_1)`. The proof certifies
|
||||
/// the analogous decryptable properties for each one of these pair of commitment and decryption
|
||||
/// handles.
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -234,7 +234,7 @@ impl AggregatedValidityProof {
|
|||
/// The function simples aggregates the input openings and invokes the standard ciphertext
|
||||
/// validity proof constructor.
|
||||
pub fn new<T: Into<Scalar>>(
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(amount_lo, amount_hi): (T, T),
|
||||
(opening_lo, opening_hi): (&PedersenOpening, &PedersenOpening),
|
||||
transcript: &mut Transcript,
|
||||
|
@ -247,7 +247,7 @@ impl AggregatedValidityProof {
|
|||
let aggregated_opening = opening_lo + &(opening_hi * &t);
|
||||
|
||||
AggregatedValidityProof(ValidityProof::new(
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
aggregated_message,
|
||||
&aggregated_opening,
|
||||
transcript,
|
||||
|
@ -263,10 +263,10 @@ impl AggregatedValidityProof {
|
|||
/// This function is randomized. It uses `OsRng` internally to generate random scalars.
|
||||
pub fn verify(
|
||||
self,
|
||||
(pubkey_dest, pubkey_auditor): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(destination_pubkey, auditor_pubkey): (&ElGamalPubkey, &ElGamalPubkey),
|
||||
(commitment_lo, commitment_hi): (&PedersenCommitment, &PedersenCommitment),
|
||||
(handle_lo_dest, handle_hi_dest): (&DecryptHandle, &DecryptHandle),
|
||||
(handle_lo_auditor, handle_hi_auditor): (&DecryptHandle, &DecryptHandle),
|
||||
(destination_handle_lo, destination_handle_hi): (&DecryptHandle, &DecryptHandle),
|
||||
(auditor_handle_lo, auditor_handle_hi): (&DecryptHandle, &DecryptHandle),
|
||||
transcript: &mut Transcript,
|
||||
) -> Result<(), ValidityProofError> {
|
||||
transcript.aggregated_validity_proof_domain_sep();
|
||||
|
@ -274,15 +274,15 @@ impl AggregatedValidityProof {
|
|||
let t = transcript.challenge_scalar(b"t");
|
||||
|
||||
let aggregated_commitment = commitment_lo + commitment_hi * t;
|
||||
let aggregated_handle_dest = handle_lo_dest + handle_hi_dest * t;
|
||||
let aggregated_handle_auditor = handle_lo_auditor + handle_hi_auditor * t;
|
||||
let destination_aggregated_handle = destination_handle_lo + destination_handle_hi * t;
|
||||
let auditor_aggregated_handle = auditor_handle_lo + auditor_handle_hi * t;
|
||||
|
||||
let AggregatedValidityProof(validity_proof) = self;
|
||||
|
||||
validity_proof.verify(
|
||||
&aggregated_commitment,
|
||||
(pubkey_dest, pubkey_auditor),
|
||||
(&aggregated_handle_dest, &aggregated_handle_auditor),
|
||||
(destination_pubkey, auditor_pubkey),
|
||||
(&destination_aggregated_handle, &auditor_aggregated_handle),
|
||||
transcript,
|
||||
)
|
||||
}
|
||||
|
@ -305,31 +305,31 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_validity_proof_correctness() {
|
||||
let elgamal_pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let elgamal_pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let amount: u64 = 55;
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
|
||||
let handle_dest = elgamal_pubkey_dest.decrypt_handle(&opening);
|
||||
let handle_auditor = elgamal_pubkey_auditor.decrypt_handle(&opening);
|
||||
let destination_handle = destination_pubkey.decrypt_handle(&opening);
|
||||
let auditor_handle = auditor_pubkey.decrypt_handle(&opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = ValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
amount,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment,
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&handle_dest, &handle_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&destination_handle, &auditor_handle),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
@ -337,127 +337,127 @@ mod test {
|
|||
#[test]
|
||||
fn test_validity_proof_edge_cases() {
|
||||
// if destination public key zeroed, then the proof should always reject
|
||||
let elgamal_pubkey_dest = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||
let elgamal_pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let destination_pubkey = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let amount: u64 = 55;
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
|
||||
let handle_dest = elgamal_pubkey_dest.decrypt_handle(&opening);
|
||||
let handle_auditor = elgamal_pubkey_auditor.decrypt_handle(&opening);
|
||||
let destination_handle = destination_pubkey.decrypt_handle(&opening);
|
||||
let auditor_handle = auditor_pubkey.decrypt_handle(&opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = ValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
amount,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment,
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&handle_dest, &handle_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&destination_handle, &auditor_handle),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// if auditor public key zeroed, then the proof should always reject
|
||||
let elgamal_pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let elgamal_pubkey_auditor = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||
|
||||
let amount: u64 = 55;
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
|
||||
let handle_dest = elgamal_pubkey_dest.decrypt_handle(&opening);
|
||||
let handle_auditor = elgamal_pubkey_auditor.decrypt_handle(&opening);
|
||||
let destination_handle = destination_pubkey.decrypt_handle(&opening);
|
||||
let auditor_handle = auditor_pubkey.decrypt_handle(&opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = ValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
amount,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment,
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&handle_dest, &handle_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&destination_handle, &auditor_handle),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// all zeroed ciphertext should still be valid
|
||||
let elgamal_pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let elgamal_pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let amount: u64 = 0;
|
||||
let commitment = PedersenCommitment::from_bytes(&[0u8; 32]).unwrap();
|
||||
let opening = PedersenOpening::from_bytes(&[0u8; 32]).unwrap();
|
||||
|
||||
let handle_dest = elgamal_pubkey_dest.decrypt_handle(&opening);
|
||||
let handle_auditor = elgamal_pubkey_auditor.decrypt_handle(&opening);
|
||||
let destination_handle = destination_pubkey.decrypt_handle(&opening);
|
||||
let auditor_handle = auditor_pubkey.decrypt_handle(&opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = ValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
amount,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment,
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&handle_dest, &handle_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&destination_handle, &auditor_handle),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// decryption handles can be zero as long as the Pedersen commitment is valid
|
||||
let elgamal_pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let elgamal_pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let amount: u64 = 55;
|
||||
let (commitment, opening) = Pedersen::new(amount);
|
||||
|
||||
let handle_dest = elgamal_pubkey_dest.decrypt_handle(&opening);
|
||||
let handle_auditor = elgamal_pubkey_auditor.decrypt_handle(&opening);
|
||||
let destination_handle = destination_pubkey.decrypt_handle(&opening);
|
||||
let auditor_handle = auditor_pubkey.decrypt_handle(&opening);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = ValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
amount,
|
||||
&opening,
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&commitment,
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&handle_dest, &handle_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&destination_handle, &auditor_handle),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_aggregated_validity_proof() {
|
||||
let elgamal_pubkey_dest = ElGamalKeypair::new_rand().public;
|
||||
let elgamal_pubkey_auditor = ElGamalKeypair::new_rand().public;
|
||||
let destination_pubkey = ElGamalKeypair::new_rand().public;
|
||||
let auditor_pubkey = ElGamalKeypair::new_rand().public;
|
||||
|
||||
let amount_lo: u64 = 55;
|
||||
let amount_hi: u64 = 77;
|
||||
|
@ -465,29 +465,29 @@ mod test {
|
|||
let (commitment_lo, open_lo) = Pedersen::new(amount_lo);
|
||||
let (commitment_hi, open_hi) = Pedersen::new(amount_hi);
|
||||
|
||||
let handle_lo_dest = elgamal_pubkey_dest.decrypt_handle(&open_lo);
|
||||
let handle_hi_dest = elgamal_pubkey_dest.decrypt_handle(&open_hi);
|
||||
let destination_handle_lo = destination_pubkey.decrypt_handle(&open_lo);
|
||||
let destination_handle_hi = destination_pubkey.decrypt_handle(&open_hi);
|
||||
|
||||
let handle_lo_auditor = elgamal_pubkey_auditor.decrypt_handle(&open_lo);
|
||||
let handle_hi_auditor = elgamal_pubkey_auditor.decrypt_handle(&open_hi);
|
||||
let auditor_handle_lo = auditor_pubkey.decrypt_handle(&open_lo);
|
||||
let auditor_handle_hi = auditor_pubkey.decrypt_handle(&open_hi);
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"Test");
|
||||
let mut transcript_verifier = Transcript::new(b"Test");
|
||||
let mut prover_transcript = Transcript::new(b"Test");
|
||||
let mut verifier_transcript = Transcript::new(b"Test");
|
||||
|
||||
let proof = AggregatedValidityProof::new(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(amount_lo, amount_hi),
|
||||
(&open_lo, &open_hi),
|
||||
&mut transcript_prover,
|
||||
&mut prover_transcript,
|
||||
);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
(&elgamal_pubkey_dest, &elgamal_pubkey_auditor),
|
||||
(&destination_pubkey, &auditor_pubkey),
|
||||
(&commitment_lo, &commitment_hi),
|
||||
(&handle_lo_dest, &handle_hi_dest),
|
||||
(&handle_lo_auditor, &handle_hi_auditor),
|
||||
&mut transcript_verifier,
|
||||
(&destination_handle_lo, &destination_handle_hi),
|
||||
(&auditor_handle_lo, &auditor_handle_hi),
|
||||
&mut verifier_transcript,
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
|
|
@ -178,30 +178,30 @@ mod test {
|
|||
fn test_zero_balance_proof_correctness() {
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
// general case: encryption of 0
|
||||
let elgamal_ciphertext = source_keypair.public.encrypt(0_u64);
|
||||
let proof =
|
||||
ZeroBalanceProof::new(&source_keypair, &elgamal_ciphertext, &mut transcript_prover);
|
||||
ZeroBalanceProof::new(&source_keypair, &elgamal_ciphertext, &mut prover_transcript);
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&elgamal_ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// general case: encryption of > 0
|
||||
let elgamal_ciphertext = source_keypair.public.encrypt(1_u64);
|
||||
let proof =
|
||||
ZeroBalanceProof::new(&source_keypair, &elgamal_ciphertext, &mut transcript_prover);
|
||||
ZeroBalanceProof::new(&source_keypair, &elgamal_ciphertext, &mut prover_transcript);
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&elgamal_ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
@ -210,26 +210,26 @@ mod test {
|
|||
fn test_zero_balance_proof_edge_cases() {
|
||||
let source_keypair = ElGamalKeypair::new_rand();
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
// all zero ciphertext should always be a valid encryption of 0
|
||||
let ciphertext = ElGamalCiphertext::from_bytes(&[0u8; 64]).unwrap();
|
||||
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut transcript_prover);
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut prover_transcript);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// if only either commitment or handle is zero, the ciphertext is always invalid and proof
|
||||
// verification should always reject
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let zeroed_commitment = PedersenCommitment::from_bytes(&[0u8; 32]).unwrap();
|
||||
let handle = source_keypair
|
||||
|
@ -241,18 +241,18 @@ mod test {
|
|||
handle,
|
||||
};
|
||||
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut transcript_prover);
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut prover_transcript);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let (zeroed_commitment, _) = Pedersen::new(0_u64);
|
||||
let ciphertext = ElGamalCiphertext {
|
||||
|
@ -260,19 +260,19 @@ mod test {
|
|||
handle: DecryptHandle::from_bytes(&[0u8; 32]).unwrap(),
|
||||
};
|
||||
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut transcript_prover);
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut prover_transcript);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// if public key is always zero, then the proof should always reject
|
||||
let mut transcript_prover = Transcript::new(b"test");
|
||||
let mut transcript_verifier = Transcript::new(b"test");
|
||||
let mut prover_transcript = Transcript::new(b"test");
|
||||
let mut verifier_transcript = Transcript::new(b"test");
|
||||
|
||||
let public = ElGamalPubkey::from_bytes(&[0u8; 32]).unwrap();
|
||||
let secret = ElGamalSecretKey::new_rand();
|
||||
|
@ -281,13 +281,13 @@ mod test {
|
|||
|
||||
let ciphertext = elgamal_keypair.public.encrypt(0_u64);
|
||||
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut transcript_prover);
|
||||
let proof = ZeroBalanceProof::new(&source_keypair, &ciphertext, &mut prover_transcript);
|
||||
|
||||
assert!(proof
|
||||
.verify(
|
||||
&source_keypair.public,
|
||||
&ciphertext,
|
||||
&mut transcript_verifier
|
||||
&mut verifier_transcript
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
|
|
@ -327,9 +327,9 @@ mod target_arch {
|
|||
impl From<TransferPubkeys> for pod::TransferPubkeys {
|
||||
fn from(keys: TransferPubkeys) -> Self {
|
||||
Self {
|
||||
pubkey_source: keys.pubkey_source.into(),
|
||||
pubkey_dest: keys.pubkey_dest.into(),
|
||||
pubkey_auditor: keys.pubkey_auditor.into(),
|
||||
source_pubkey: keys.source_pubkey.into(),
|
||||
destination_pubkey: keys.destination_pubkey.into(),
|
||||
auditor_pubkey: keys.auditor_pubkey.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,9 +339,9 @@ mod target_arch {
|
|||
|
||||
fn try_from(pod: pod::TransferPubkeys) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
pubkey_source: pod.pubkey_source.try_into()?,
|
||||
pubkey_dest: pod.pubkey_dest.try_into()?,
|
||||
pubkey_auditor: pod.pubkey_auditor.try_into()?,
|
||||
source_pubkey: pod.source_pubkey.try_into()?,
|
||||
destination_pubkey: pod.destination_pubkey.try_into()?,
|
||||
auditor_pubkey: pod.auditor_pubkey.try_into()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -349,10 +349,10 @@ mod target_arch {
|
|||
impl From<TransferWithFeePubkeys> for pod::TransferWithFeePubkeys {
|
||||
fn from(keys: TransferWithFeePubkeys) -> Self {
|
||||
Self {
|
||||
pubkey_source: keys.pubkey_source.into(),
|
||||
pubkey_dest: keys.pubkey_dest.into(),
|
||||
pubkey_auditor: keys.pubkey_auditor.into(),
|
||||
pubkey_withdraw_withheld_authority: keys.pubkey_withdraw_withheld_authority.into(),
|
||||
source_pubkey: keys.source_pubkey.into(),
|
||||
destination_pubkey: keys.destination_pubkey.into(),
|
||||
auditor_pubkey: keys.auditor_pubkey.into(),
|
||||
withdraw_withheld_authority_pubkey: keys.withdraw_withheld_authority_pubkey.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -362,11 +362,11 @@ mod target_arch {
|
|||
|
||||
fn try_from(pod: pod::TransferWithFeePubkeys) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
pubkey_source: pod.pubkey_source.try_into()?,
|
||||
pubkey_dest: pod.pubkey_dest.try_into()?,
|
||||
pubkey_auditor: pod.pubkey_auditor.try_into()?,
|
||||
pubkey_withdraw_withheld_authority: pod
|
||||
.pubkey_withdraw_withheld_authority
|
||||
source_pubkey: pod.source_pubkey.try_into()?,
|
||||
destination_pubkey: pod.destination_pubkey.try_into()?,
|
||||
auditor_pubkey: pod.auditor_pubkey.try_into()?,
|
||||
withdraw_withheld_authority_pubkey: pod
|
||||
.withdraw_withheld_authority_pubkey
|
||||
.try_into()?,
|
||||
})
|
||||
}
|
||||
|
@ -376,9 +376,9 @@ mod target_arch {
|
|||
fn from(ciphertext: TransferAmountEncryption) -> Self {
|
||||
Self {
|
||||
commitment: ciphertext.commitment.into(),
|
||||
handle_source: ciphertext.handle_source.into(),
|
||||
handle_dest: ciphertext.handle_dest.into(),
|
||||
handle_auditor: ciphertext.handle_auditor.into(),
|
||||
source_handle: ciphertext.source_handle.into(),
|
||||
destination_handle: ciphertext.destination_handle.into(),
|
||||
auditor_handle: ciphertext.auditor_handle.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,9 +389,9 @@ mod target_arch {
|
|||
fn try_from(pod: pod::TransferAmountEncryption) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
commitment: pod.commitment.try_into()?,
|
||||
handle_source: pod.handle_source.try_into()?,
|
||||
handle_dest: pod.handle_dest.try_into()?,
|
||||
handle_auditor: pod.handle_auditor.try_into()?,
|
||||
source_handle: pod.source_handle.try_into()?,
|
||||
destination_handle: pod.destination_handle.try_into()?,
|
||||
auditor_handle: pod.auditor_handle.try_into()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -400,9 +400,9 @@ mod target_arch {
|
|||
fn from(ciphertext: FeeEncryption) -> Self {
|
||||
Self {
|
||||
commitment: ciphertext.commitment.into(),
|
||||
handle_dest: ciphertext.handle_dest.into(),
|
||||
handle_withdraw_withheld_authority: ciphertext
|
||||
.handle_withdraw_withheld_authority
|
||||
destination_handle: ciphertext.destination_handle.into(),
|
||||
withdraw_withheld_authority_handle: ciphertext
|
||||
.withdraw_withheld_authority_handle
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
|
@ -414,9 +414,9 @@ mod target_arch {
|
|||
fn try_from(pod: pod::FeeEncryption) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
commitment: pod.commitment.try_into()?,
|
||||
handle_dest: pod.handle_dest.try_into()?,
|
||||
handle_withdraw_withheld_authority: pod
|
||||
.handle_withdraw_withheld_authority
|
||||
destination_handle: pod.destination_handle.try_into()?,
|
||||
withdraw_withheld_authority_handle: pod
|
||||
.withdraw_withheld_authority_handle
|
||||
.try_into()?,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -194,35 +194,35 @@ impl Default for AeCiphertext {
|
|||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct TransferPubkeys {
|
||||
pub pubkey_source: ElGamalPubkey,
|
||||
pub pubkey_dest: ElGamalPubkey,
|
||||
pub pubkey_auditor: ElGamalPubkey,
|
||||
pub source_pubkey: ElGamalPubkey,
|
||||
pub destination_pubkey: ElGamalPubkey,
|
||||
pub auditor_pubkey: ElGamalPubkey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct TransferWithFeePubkeys {
|
||||
pub pubkey_source: ElGamalPubkey,
|
||||
pub pubkey_dest: ElGamalPubkey,
|
||||
pub pubkey_auditor: ElGamalPubkey,
|
||||
pub pubkey_withdraw_withheld_authority: ElGamalPubkey,
|
||||
pub source_pubkey: ElGamalPubkey,
|
||||
pub destination_pubkey: ElGamalPubkey,
|
||||
pub auditor_pubkey: ElGamalPubkey,
|
||||
pub withdraw_withheld_authority_pubkey: ElGamalPubkey,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct TransferAmountEncryption {
|
||||
pub commitment: PedersenCommitment,
|
||||
pub handle_source: DecryptHandle,
|
||||
pub handle_dest: DecryptHandle,
|
||||
pub handle_auditor: DecryptHandle,
|
||||
pub source_handle: DecryptHandle,
|
||||
pub destination_handle: DecryptHandle,
|
||||
pub auditor_handle: DecryptHandle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct FeeEncryption {
|
||||
pub commitment: PedersenCommitment,
|
||||
pub handle_dest: DecryptHandle,
|
||||
pub handle_withdraw_withheld_authority: DecryptHandle,
|
||||
pub destination_handle: DecryptHandle,
|
||||
pub withdraw_withheld_authority_handle: DecryptHandle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
|
|
Loading…
Reference in New Issue