Merge transfer instructions

This commit is contained in:
Michael Vines 2021-10-04 13:14:48 -07:00
parent 42f7c0c7f6
commit 17cda46531
3 changed files with 25 additions and 38 deletions

View File

@ -7,10 +7,7 @@ mod withdraw;
use crate::errors::ProofError; use crate::errors::ProofError;
pub use { pub use {
close_account::CloseAccountData, close_account::CloseAccountData,
transfer::{ transfer::{TransferComms, TransferData, TransferPubKeys},
TransferComms, TransferData, TransferEphemeralState, TransferPubKeys,
TransferRangeProofData, TransferValidityProofData,
},
update_account_pk::UpdateAccountPkData, update_account_pk::UpdateAccountPkData,
withdraw::WithdrawData, withdraw::WithdrawData,
}; };

View File

@ -26,9 +26,12 @@ use {
/// Just a grouping struct for the data required for the two transfer instructions. It is /// Just a grouping struct for the data required for the two transfer instructions. It is
/// convenient to generate the two components jointly as they share common components. /// convenient to generate the two components jointly as they share common components.
#[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)]
pub struct TransferData { pub struct TransferData {
pub range_proof: TransferRangeProofData, pub range_proof: TransferRangeProofData,
pub validity_proof: TransferValidityProofData, pub validity_proof: TransferValidityProofData,
ephemeral_state: TransferEphemeralState, // 128 bytes
} }
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
@ -116,7 +119,6 @@ impl TransferData {
let range_proof = TransferRangeProofData { let range_proof = TransferRangeProofData {
amount_comms, amount_comms,
proof: transfer_proofs.range_proof, proof: transfer_proofs.range_proof,
ephemeral_state,
}; };
let validity_proof = TransferValidityProofData { let validity_proof = TransferValidityProofData {
@ -125,12 +127,12 @@ impl TransferData {
transfer_public_keys, transfer_public_keys,
new_spendable_ct: new_spendable_ct.into(), new_spendable_ct: new_spendable_ct.into(),
proof: transfer_proofs.validity_proof, proof: transfer_proofs.validity_proof,
ephemeral_state,
}; };
TransferData { TransferData {
range_proof, range_proof,
validity_proof, validity_proof,
ephemeral_state,
} }
} }
@ -173,6 +175,14 @@ impl TransferData {
} }
} }
#[cfg(not(target_arch = "bpf"))]
impl Verifiable for TransferData {
fn verify(&self) -> Result<(), ProofError> {
self.range_proof.verify(&self.ephemeral_state)?;
self.validity_proof.verify(&self.ephemeral_state)
}
}
#[derive(Clone, Copy, Pod, Zeroable)] #[derive(Clone, Copy, Pod, Zeroable)]
#[repr(C)] #[repr(C)]
pub struct TransferRangeProofData { pub struct TransferRangeProofData {
@ -184,27 +194,24 @@ pub struct TransferRangeProofData {
/// 64-bit positive number) /// 64-bit positive number)
/// 2. the transfer amount is a 64-bit positive number /// 2. the transfer amount is a 64-bit positive number
pub proof: pod::RangeProof128, // 736 bytes pub proof: pod::RangeProof128, // 736 bytes
/// Ephemeral state between the two transfer instruction data
pub ephemeral_state: TransferEphemeralState, // 128 bytes
} }
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
impl Verifiable for TransferRangeProofData { impl TransferRangeProofData {
fn verify(&self) -> Result<(), ProofError> { fn verify(&self, ephemeral_state: &TransferEphemeralState) -> Result<(), ProofError> {
let mut transcript = Transcript::new(b"TransferRangeProof"); let mut transcript = Transcript::new(b"TransferRangeProof");
// standard range proof verification // standard range proof verification
let proof: RangeProof = self.proof.try_into()?; let proof: RangeProof = self.proof.try_into()?;
proof.verify_with( proof.verify_with(
vec![ vec![
&self.ephemeral_state.spendable_comm_verification.into(), &ephemeral_state.spendable_comm_verification.into(),
&self.amount_comms.lo.into(), &self.amount_comms.lo.into(),
&self.amount_comms.hi.into(), &self.amount_comms.hi.into(),
], ],
vec![64_usize, 32_usize, 32_usize], vec![64_usize, 32_usize, 32_usize],
Some(self.ephemeral_state.x.into()), Some(ephemeral_state.x.into()),
Some(self.ephemeral_state.z.into()), Some(ephemeral_state.z.into()),
&mut transcript, &mut transcript,
) )
} }
@ -227,9 +234,6 @@ pub struct TransferValidityProofData {
/// Proof that certifies that the decryption handles are generated correctly /// Proof that certifies that the decryption handles are generated correctly
pub proof: ValidityProof, // 160 bytes pub proof: ValidityProof, // 160 bytes
/// Ephemeral state between the two transfer instruction data
pub ephemeral_state: TransferEphemeralState, // 128 bytes
} }
/// The joint data that is shared between the two transfer instructions. /// The joint data that is shared between the two transfer instructions.
@ -246,14 +250,14 @@ pub struct TransferEphemeralState {
} }
#[cfg(not(target_arch = "bpf"))] #[cfg(not(target_arch = "bpf"))]
impl Verifiable for TransferValidityProofData { impl TransferValidityProofData {
fn verify(&self) -> Result<(), ProofError> { fn verify(&self, ephemeral_state: &TransferEphemeralState) -> Result<(), ProofError> {
self.proof.verify( self.proof.verify(
&self.new_spendable_ct.try_into()?, &self.new_spendable_ct.try_into()?,
&self.decryption_handles_lo, &self.decryption_handles_lo,
&self.decryption_handles_hi, &self.decryption_handles_hi,
&self.transfer_public_keys, &self.transfer_public_keys,
&self.ephemeral_state, ephemeral_state,
) )
} }
} }
@ -576,11 +580,7 @@ mod test {
auditor_pk, auditor_pk,
); );
// verify range proof assert!(transfer_data.verify().is_ok());
assert!(transfer_data.range_proof.verify().is_ok());
// verify ciphertext validity proof
assert!(transfer_data.validity_proof.verify().is_ok());
} }
#[test] #[test]

View File

@ -41,25 +41,15 @@ pub enum ProofInstruction {
/// ///
VerifyWithdraw, VerifyWithdraw,
/// Verify a `TransferRangeProofData` struct /// Verify a `TransferData` struct
/// ///
/// Accounts expected by this instruction: /// Accounts expected by this instruction:
/// None /// None
/// ///
/// Data expected by this instruction: /// Data expected by this instruction:
/// `TransferRangeProofData` /// `TransferData`
/// ///
VerifyTransferRangeProofData, VerifyTransfer,
/// Verify a `TransferValidityProofData` struct
///
/// Accounts expected by this instruction:
/// None
///
/// Data expected by this instruction:
/// `TransferValidityProofData`
///
VerifyTransferValidityProofData,
} }
impl ProofInstruction { impl ProofInstruction {