cleaning up transfer proof
This commit is contained in:
parent
30e12aef9a
commit
ccdbe65c87
|
@ -6,7 +6,7 @@ mod withdraw;
|
||||||
use crate::errors::ProofError;
|
use crate::errors::ProofError;
|
||||||
pub use {
|
pub use {
|
||||||
close_account::CloseAccountData,
|
close_account::CloseAccountData,
|
||||||
transfer::{TransferCommitments, TransferData, TransferPubKeys},
|
transfer::{TransferCommitments, TransferData, TransferPubkeys},
|
||||||
withdraw::WithdrawData,
|
withdraw::WithdrawData,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,12 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
encryption::{
|
encryption::{
|
||||||
discrete_log::*,
|
discrete_log::*,
|
||||||
elgamal::{ElGamalCiphertext, ElGamalPubkey, ElGamalSecretKey},
|
elgamal::{ElGamalCiphertext, ElGamalKeypair, ElGamalPubkey, ElGamalSecretKey},
|
||||||
pedersen::{
|
pedersen::{
|
||||||
Pedersen, PedersenBase, PedersenCommitment, PedersenDecryptHandle, PedersenOpening,
|
Pedersen, PedersenBase, PedersenCommitment, PedersenDecryptHandle, PedersenOpening,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
equality_proof::EqualityProof,
|
||||||
errors::ProofError,
|
errors::ProofError,
|
||||||
instruction::{Role, Verifiable},
|
instruction::{Role, Verifiable},
|
||||||
range_proof::RangeProof,
|
range_proof::RangeProof,
|
||||||
|
@ -40,7 +41,7 @@ pub struct TransferData {
|
||||||
pub decrypt_handles_hi: TransferDecryptHandles,
|
pub decrypt_handles_hi: TransferDecryptHandles,
|
||||||
|
|
||||||
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
/// The public encryption keys associated with the transfer: source, dest, and auditor
|
||||||
pub transfer_public_keys: TransferPubKeys, // 96 bytes
|
pub transfer_public_keys: TransferPubkeys, // 96 bytes
|
||||||
|
|
||||||
/// The final spendable ciphertext after the transfer
|
/// The final spendable ciphertext after the transfer
|
||||||
pub new_spendable_ct: pod::ElGamalCiphertext, // 64 bytes
|
pub new_spendable_ct: pod::ElGamalCiphertext, // 64 bytes
|
||||||
|
@ -56,8 +57,7 @@ impl TransferData {
|
||||||
transfer_amount: u64,
|
transfer_amount: u64,
|
||||||
spendable_balance: u64,
|
spendable_balance: u64,
|
||||||
spendable_ct: ElGamalCiphertext,
|
spendable_ct: ElGamalCiphertext,
|
||||||
source_pk: ElGamalPubkey,
|
source_keypair: &ElGamalKeypair,
|
||||||
source_sk: &ElGamalSecretKey,
|
|
||||||
dest_pk: ElGamalPubkey,
|
dest_pk: ElGamalPubkey,
|
||||||
auditor_pk: ElGamalPubkey,
|
auditor_pk: ElGamalPubkey,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -70,11 +70,11 @@ impl TransferData {
|
||||||
let (comm_lo, open_lo) = Pedersen::new(amount_lo);
|
let (comm_lo, open_lo) = Pedersen::new(amount_lo);
|
||||||
let (comm_hi, open_hi) = Pedersen::new(amount_hi);
|
let (comm_hi, open_hi) = Pedersen::new(amount_hi);
|
||||||
|
|
||||||
let handle_source_lo = source_pk.decrypt_handle(&open_lo);
|
let handle_source_lo = source_keypair.public.decrypt_handle(&open_lo);
|
||||||
let handle_dest_lo = dest_pk.decrypt_handle(&open_lo);
|
let handle_dest_lo = dest_pk.decrypt_handle(&open_lo);
|
||||||
let handle_auditor_lo = auditor_pk.decrypt_handle(&open_lo);
|
let handle_auditor_lo = auditor_pk.decrypt_handle(&open_lo);
|
||||||
|
|
||||||
let handle_source_hi = source_pk.decrypt_handle(&open_hi);
|
let handle_source_hi = source_keypair.public.decrypt_handle(&open_hi);
|
||||||
let handle_dest_hi = dest_pk.decrypt_handle(&open_hi);
|
let handle_dest_hi = dest_pk.decrypt_handle(&open_hi);
|
||||||
let handle_auditor_hi = auditor_pk.decrypt_handle(&open_hi);
|
let handle_auditor_hi = auditor_pk.decrypt_handle(&open_hi);
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ impl TransferData {
|
||||||
};
|
};
|
||||||
|
|
||||||
// grouping of the public keys for the transfer
|
// grouping of the public keys for the transfer
|
||||||
let transfer_public_keys = TransferPubKeys {
|
let transfer_public_keys = TransferPubkeys {
|
||||||
source_pk: source_pk.into(),
|
source_pk: source_keypair.public.into(),
|
||||||
dest_pk: dest_pk.into(),
|
dest_pk: dest_pk.into(),
|
||||||
auditor_pk: auditor_pk.into(),
|
auditor_pk: auditor_pk.into(),
|
||||||
};
|
};
|
||||||
|
@ -120,8 +120,7 @@ impl TransferData {
|
||||||
|
|
||||||
// range_proof and validity_proof should be generated together
|
// range_proof and validity_proof should be generated together
|
||||||
let proof = TransferProof::new(
|
let proof = TransferProof::new(
|
||||||
source_sk,
|
&source_keypair,
|
||||||
&source_pk,
|
|
||||||
&dest_pk,
|
&dest_pk,
|
||||||
&auditor_pk,
|
&auditor_pk,
|
||||||
(amount_lo as u64, amount_hi as u64),
|
(amount_lo as u64, amount_hi as u64),
|
||||||
|
@ -207,221 +206,142 @@ impl Verifiable for TransferData {
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransferProof {
|
pub struct TransferProof {
|
||||||
// Proof component for the spendable ciphertext components: R
|
/// New Pedersen commitment for the remaining balance in source
|
||||||
pub R: pod::CompressedRistretto, // 32 bytes
|
pub source_commitment: pod::PedersenCommitment,
|
||||||
// Proof component for the spendable ciphertext components: z
|
|
||||||
pub z: pod::Scalar, // 32 bytes
|
/// Associated equality proof
|
||||||
// Proof component for the transaction amount components: T_src
|
pub equality_proof: pod::EqualityProof,
|
||||||
pub T_joint: pod::CompressedRistretto, // 32 bytes
|
|
||||||
// Proof component for the transaction amount components: T_1
|
// Associated range proof
|
||||||
pub T_1: pod::CompressedRistretto, // 32 bytes
|
|
||||||
// Proof component for the transaction amount components: T_2
|
|
||||||
pub T_2: pod::CompressedRistretto, // 32 bytes
|
|
||||||
// Range proof component
|
|
||||||
pub range_proof: pod::RangeProof128,
|
pub range_proof: pod::RangeProof128,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
#[cfg(not(target_arch = "bpf"))]
|
||||||
impl TransferProof {
|
impl TransferProof {
|
||||||
|
fn transcript_new() -> Transcript {
|
||||||
|
Transcript::new(b"TransferProof")
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[allow(clippy::many_single_char_names)]
|
#[allow(clippy::many_single_char_names)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
source_sk: &ElGamalSecretKey,
|
source_keypair: &ElGamalKeypair,
|
||||||
source_pk: &ElGamalPubkey,
|
|
||||||
dest_pk: &ElGamalPubkey,
|
dest_pk: &ElGamalPubkey,
|
||||||
auditor_pk: &ElGamalPubkey,
|
auditor_pk: &ElGamalPubkey,
|
||||||
transfer_amt: (u64, u64),
|
transfer_amt: (u64, u64),
|
||||||
lo_open: &PedersenOpening,
|
lo_open: &PedersenOpening,
|
||||||
hi_open: &PedersenOpening,
|
hi_open: &PedersenOpening,
|
||||||
new_spendable_balance: u64,
|
source_new_balance: u64,
|
||||||
new_spendable_ct: &ElGamalCiphertext,
|
source_new_balance_ct: &ElGamalCiphertext,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// TODO: should also commit to pubkeys and commitments later
|
let mut transcript = Self::transcript_new();
|
||||||
let mut transcript = merlin::Transcript::new(b"TransferProof");
|
|
||||||
|
|
||||||
let H = PedersenBase::default().H;
|
// add a domain separator to record the start of the protocol
|
||||||
let D = new_spendable_ct.decrypt_handle.get_point();
|
transcript.transfer_proof_domain_sep();
|
||||||
let s = source_sk.get_scalar();
|
|
||||||
|
|
||||||
// Generate proof for the new spendable ciphertext
|
// generate a Pedersen commitment for the remaining balance in source
|
||||||
let r_new = Scalar::random(&mut OsRng);
|
let (source_commitment, source_open) = Pedersen::new(source_new_balance);
|
||||||
let y = Scalar::random(&mut OsRng);
|
|
||||||
let R = RistrettoPoint::multiscalar_mul(vec![y, r_new], vec![D, H]).compress();
|
|
||||||
|
|
||||||
transcript.append_point(b"R", &R);
|
// extract the relevant scalar and Ristretto points from the inputs
|
||||||
let c = transcript.challenge_scalar(b"c");
|
let P_EG = source_keypair.public.get_point();
|
||||||
|
let C_EG = source_new_balance_ct.message_comm.get_point();
|
||||||
|
let D_EG = source_new_balance_ct.decrypt_handle.get_point();
|
||||||
|
let C_Ped = source_commitment.get_point();
|
||||||
|
|
||||||
let z = s + c * y;
|
// append all current state to the transcript
|
||||||
let new_spendable_open = PedersenOpening(c * r_new);
|
transcript.append_point(b"P_EG", &P_EG.compress());
|
||||||
|
transcript.append_point(b"C_EG", &C_EG.compress());
|
||||||
|
transcript.append_point(b"D_EG", &D_EG.compress());
|
||||||
|
transcript.append_point(b"C_Ped", &C_Ped.compress());
|
||||||
|
|
||||||
// Generate proof for the transfer amounts
|
// let c = transcript.challenge_scalar(b"c");
|
||||||
let t_1_blinding = PedersenOpening::random(&mut OsRng);
|
// println!("{:?}", c);
|
||||||
let t_2_blinding = PedersenOpening::random(&mut OsRng);
|
|
||||||
|
|
||||||
// generate the range proof
|
// generate equality_proof
|
||||||
let range_proof = RangeProof::create_with(
|
let equality_proof = EqualityProof::new(
|
||||||
vec![new_spendable_balance, transfer_amt.0, transfer_amt.1],
|
source_keypair,
|
||||||
vec![64, 32, 32],
|
source_new_balance_ct,
|
||||||
vec![&new_spendable_open, lo_open, hi_open],
|
source_new_balance,
|
||||||
&t_1_blinding,
|
&source_open,
|
||||||
&t_2_blinding,
|
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
);
|
);
|
||||||
|
|
||||||
let u = transcript.challenge_scalar(b"u");
|
// TODO: Add ct validity proof
|
||||||
|
|
||||||
let P_joint = RistrettoPoint::multiscalar_mul(
|
// generate the range proof
|
||||||
vec![Scalar::one(), u, u * u],
|
let range_proof = RangeProof::create(
|
||||||
vec![
|
vec![source_new_balance, transfer_amt.0, transfer_amt.1],
|
||||||
source_pk.get_point(),
|
vec![64, 32, 32],
|
||||||
dest_pk.get_point(),
|
vec![&source_open, lo_open, hi_open],
|
||||||
auditor_pk.get_point(),
|
&mut transcript,
|
||||||
],
|
|
||||||
);
|
);
|
||||||
let T_joint = (new_spendable_open.get_scalar() * P_joint).compress();
|
|
||||||
let T_1 = (t_1_blinding.get_scalar() * P_joint).compress();
|
|
||||||
let T_2 = (t_2_blinding.get_scalar() * P_joint).compress();
|
|
||||||
|
|
||||||
transcript.append_point(b"T_1", &T_1);
|
|
||||||
transcript.append_point(b"T_2", &T_2);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
R: R.into(),
|
source_commitment: source_commitment.into(),
|
||||||
z: z.into(),
|
equality_proof: equality_proof.try_into().expect("equality proof"),
|
||||||
T_joint: T_joint.into(),
|
range_proof: range_proof.try_into().expect("range proof"),
|
||||||
T_1: T_1.into(),
|
|
||||||
T_2: T_2.into(),
|
|
||||||
range_proof: range_proof.try_into().expect("invalid range proof"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
#[cfg(not(target_arch = "bpf"))]
|
|
||||||
impl TransferProof {
|
|
||||||
pub fn verify(
|
pub fn verify(
|
||||||
self,
|
self,
|
||||||
amount_comms: &TransferCommitments,
|
amount_comms: &TransferCommitments,
|
||||||
decryption_handles_lo: &TransferDecryptHandles,
|
decryption_handles_lo: &TransferDecryptHandles,
|
||||||
decryption_handles_hi: &TransferDecryptHandles,
|
decryption_handles_hi: &TransferDecryptHandles,
|
||||||
new_spendable_ct: &pod::ElGamalCiphertext,
|
new_spendable_ct: &pod::ElGamalCiphertext,
|
||||||
transfer_public_keys: &TransferPubKeys,
|
transfer_public_keys: &TransferPubkeys,
|
||||||
) -> Result<(), ProofError> {
|
) -> Result<(), ProofError> {
|
||||||
let mut transcript = Transcript::new(b"TransferProof");
|
let mut transcript = Self::transcript_new();
|
||||||
|
|
||||||
|
let commitment: PedersenCommitment = self.source_commitment.try_into()?;
|
||||||
|
let equality_proof: EqualityProof = self.equality_proof.try_into()?;
|
||||||
let range_proof: RangeProof = self.range_proof.try_into()?;
|
let range_proof: RangeProof = self.range_proof.try_into()?;
|
||||||
|
|
||||||
let source_pk: ElGamalPubkey = transfer_public_keys.source_pk.try_into()?;
|
// add a domain separator to record the start of the protocol
|
||||||
let dest_pk: ElGamalPubkey = transfer_public_keys.dest_pk.try_into()?;
|
transcript.transfer_proof_domain_sep();
|
||||||
let auditor_pk: ElGamalPubkey = transfer_public_keys.auditor_pk.try_into()?;
|
|
||||||
|
|
||||||
// derive Pedersen commitment for range proof verification
|
// extract the relevant scalar and Ristretto points from the inputs
|
||||||
|
let source_pk: ElGamalPubkey = transfer_public_keys.source_pk.try_into()?;
|
||||||
let new_spendable_ct: ElGamalCiphertext = (*new_spendable_ct).try_into()?;
|
let new_spendable_ct: ElGamalCiphertext = (*new_spendable_ct).try_into()?;
|
||||||
|
|
||||||
let C = new_spendable_ct.message_comm.get_point();
|
let P_EG = source_pk.get_point();
|
||||||
let D = new_spendable_ct.decrypt_handle.get_point();
|
let C_EG = new_spendable_ct.message_comm.get_point();
|
||||||
|
let D_EG = new_spendable_ct.decrypt_handle.get_point();
|
||||||
|
let C_Ped = commitment.get_point();
|
||||||
|
|
||||||
let R = self.R.into();
|
// append all current state to the transcript
|
||||||
let z: Scalar = self.z.into();
|
transcript.append_point(b"P_EG", &P_EG.compress());
|
||||||
|
transcript.append_point(b"C_EG", &C_EG.compress());
|
||||||
|
transcript.append_point(b"D_EG", &D_EG.compress());
|
||||||
|
transcript.append_point(b"C_Ped", &C_Ped.compress());
|
||||||
|
|
||||||
transcript.validate_and_append_point(b"R", &R)?;
|
// verify equality proof
|
||||||
let c = transcript.challenge_scalar(b"c");
|
//
|
||||||
|
// TODO: we can also consider verifying equality and range proof in a batch
|
||||||
|
equality_proof.verify(&source_pk, &new_spendable_ct, &commitment, &mut transcript)?;
|
||||||
|
|
||||||
let R = R.decompress().ok_or(ProofError::VerificationError)?;
|
// TODO: validity proof
|
||||||
|
|
||||||
let spendable_comm_verification =
|
|
||||||
RistrettoPoint::multiscalar_mul(vec![Scalar::one(), -z, c], vec![C, D, R]).compress();
|
|
||||||
|
|
||||||
// verify range proof
|
// verify range proof
|
||||||
let range_proof_verification = range_proof.verify_challenges(
|
range_proof.verify(
|
||||||
vec![
|
vec![
|
||||||
&spendable_comm_verification,
|
&self.source_commitment.into(),
|
||||||
&amount_comms.lo.into(),
|
&amount_comms.lo.into(),
|
||||||
&amount_comms.hi.into(),
|
&amount_comms.hi.into(),
|
||||||
],
|
],
|
||||||
vec![64_usize, 32_usize, 32_usize],
|
vec![64_usize, 32_usize, 32_usize],
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
if range_proof_verification.is_err() {
|
Ok(())
|
||||||
return Err(ProofError::VerificationError);
|
|
||||||
}
|
|
||||||
let (z, x) = range_proof_verification.unwrap();
|
|
||||||
|
|
||||||
// check well-formedness of decryption handles
|
|
||||||
|
|
||||||
// derive joint public key
|
|
||||||
let u = transcript.challenge_scalar(b"u");
|
|
||||||
let P_joint = RistrettoPoint::vartime_multiscalar_mul(
|
|
||||||
vec![Scalar::one(), u, u * u],
|
|
||||||
vec![
|
|
||||||
source_pk.get_point(),
|
|
||||||
dest_pk.get_point(),
|
|
||||||
auditor_pk.get_point(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
let t_x_blinding: Scalar = range_proof.t_x_blinding;
|
|
||||||
let T_1: CompressedRistretto = self.T_1.into();
|
|
||||||
let T_2: CompressedRistretto = self.T_2.into();
|
|
||||||
|
|
||||||
let handle_source_lo: PedersenDecryptHandle = decryption_handles_lo.source.try_into()?;
|
|
||||||
let handle_dest_lo: PedersenDecryptHandle = decryption_handles_lo.dest.try_into()?;
|
|
||||||
let handle_auditor_lo: PedersenDecryptHandle = decryption_handles_lo.auditor.try_into()?;
|
|
||||||
|
|
||||||
let D_joint: CompressedRistretto = self.T_joint.into();
|
|
||||||
let D_joint = D_joint.decompress().ok_or(ProofError::VerificationError)?;
|
|
||||||
|
|
||||||
let D_joint_lo = RistrettoPoint::vartime_multiscalar_mul(
|
|
||||||
vec![Scalar::one(), u, u * u],
|
|
||||||
vec![
|
|
||||||
handle_source_lo.get_point(),
|
|
||||||
handle_dest_lo.get_point(),
|
|
||||||
handle_auditor_lo.get_point(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
let handle_source_hi: PedersenDecryptHandle = decryption_handles_hi.source.try_into()?;
|
|
||||||
let handle_dest_hi: PedersenDecryptHandle = decryption_handles_hi.dest.try_into()?;
|
|
||||||
let handle_auditor_hi: PedersenDecryptHandle = decryption_handles_hi.auditor.try_into()?;
|
|
||||||
|
|
||||||
let D_joint_hi = RistrettoPoint::vartime_multiscalar_mul(
|
|
||||||
vec![Scalar::one(), u, u * u],
|
|
||||||
vec![
|
|
||||||
handle_source_hi.get_point(),
|
|
||||||
handle_dest_hi.get_point(),
|
|
||||||
handle_auditor_hi.get_point(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: combine Pedersen commitment verification above to here for efficiency
|
|
||||||
// TODO: might need to add an additional proof-of-knowledge here (additional 64 byte)
|
|
||||||
let mega_check = RistrettoPoint::optional_multiscalar_mul(
|
|
||||||
vec![-t_x_blinding, x, x * x, z * z, z * z * z, z * z * z * z],
|
|
||||||
vec![
|
|
||||||
Some(P_joint),
|
|
||||||
T_1.decompress(),
|
|
||||||
T_2.decompress(),
|
|
||||||
Some(D_joint),
|
|
||||||
Some(D_joint_lo),
|
|
||||||
Some(D_joint_hi),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.ok_or(ProofError::VerificationError)?;
|
|
||||||
|
|
||||||
if mega_check.is_identity() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ProofError::VerificationError)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The ElGamal public keys needed for a transfer
|
/// The ElGamal public keys needed for a transfer
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TransferPubKeys {
|
pub struct TransferPubkeys {
|
||||||
pub source_pk: pod::ElGamalPubkey, // 32 bytes
|
pub source_pk: pod::ElGamalPubkey, // 32 bytes
|
||||||
pub dest_pk: pod::ElGamalPubkey, // 32 bytes
|
pub dest_pk: pod::ElGamalPubkey, // 32 bytes
|
||||||
pub auditor_pk: pod::ElGamalPubkey, // 32 bytes
|
pub auditor_pk: pod::ElGamalPubkey, // 32 bytes
|
||||||
|
@ -485,16 +405,13 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_transfer_correctness() {
|
fn test_transfer_correctness() {
|
||||||
// ElGamalKeypair keys for source, destination, and auditor accounts
|
// ElGamalKeypair keys for source, destination, and auditor accounts
|
||||||
let ElGamalKeypair {
|
let source_keypair = ElGamalKeypair::default();
|
||||||
public: source_pk,
|
|
||||||
secret: source_sk,
|
|
||||||
} = ElGamalKeypair::default();
|
|
||||||
let dest_pk = ElGamalKeypair::default().public;
|
let dest_pk = ElGamalKeypair::default().public;
|
||||||
let auditor_pk = ElGamalKeypair::default().public;
|
let auditor_pk = ElGamalKeypair::default().public;
|
||||||
|
|
||||||
// create source account spendable ciphertext
|
// create source account spendable ciphertext
|
||||||
let spendable_balance: u64 = 77;
|
let spendable_balance: u64 = 77;
|
||||||
let spendable_ct = source_pk.encrypt(spendable_balance);
|
let spendable_ct = source_keypair.public.encrypt(spendable_balance);
|
||||||
|
|
||||||
// transfer amount
|
// transfer amount
|
||||||
let transfer_amount: u64 = 55;
|
let transfer_amount: u64 = 55;
|
||||||
|
@ -504,8 +421,7 @@ mod test {
|
||||||
transfer_amount,
|
transfer_amount,
|
||||||
spendable_balance,
|
spendable_balance,
|
||||||
spendable_ct,
|
spendable_ct,
|
||||||
source_pk,
|
&source_keypair,
|
||||||
&source_sk,
|
|
||||||
dest_pk,
|
dest_pk,
|
||||||
auditor_pk,
|
auditor_pk,
|
||||||
);
|
);
|
||||||
|
@ -516,10 +432,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_source_dest_ciphertext() {
|
fn test_source_dest_ciphertext() {
|
||||||
// ElGamalKeypair keys for source, destination, and auditor accounts
|
// ElGamalKeypair keys for source, destination, and auditor accounts
|
||||||
let ElGamalKeypair {
|
let source_keypair = ElGamalKeypair::default();
|
||||||
public: source_pk,
|
|
||||||
secret: source_sk,
|
|
||||||
} = ElGamalKeypair::default();
|
|
||||||
|
|
||||||
let ElGamalKeypair {
|
let ElGamalKeypair {
|
||||||
public: dest_pk,
|
public: dest_pk,
|
||||||
|
@ -533,7 +446,7 @@ mod test {
|
||||||
|
|
||||||
// create source account spendable ciphertext
|
// create source account spendable ciphertext
|
||||||
let spendable_balance: u64 = 77;
|
let spendable_balance: u64 = 77;
|
||||||
let spendable_ct = source_pk.encrypt(spendable_balance);
|
let spendable_ct = source_keypair.public.encrypt(spendable_balance);
|
||||||
|
|
||||||
// transfer amount
|
// transfer amount
|
||||||
let transfer_amount: u64 = 55;
|
let transfer_amount: u64 = 55;
|
||||||
|
@ -543,15 +456,14 @@ mod test {
|
||||||
transfer_amount,
|
transfer_amount,
|
||||||
spendable_balance,
|
spendable_balance,
|
||||||
spendable_ct,
|
spendable_ct,
|
||||||
source_pk,
|
&source_keypair,
|
||||||
&source_sk,
|
|
||||||
dest_pk,
|
dest_pk,
|
||||||
auditor_pk,
|
auditor_pk,
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
transfer_data
|
transfer_data
|
||||||
.decrypt_amount(Role::Source, &source_sk)
|
.decrypt_amount(Role::Source, &source_keypair.secret)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
55_u64,
|
55_u64,
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,11 +6,11 @@ use {
|
||||||
|
|
||||||
pub trait TranscriptProtocol {
|
pub trait TranscriptProtocol {
|
||||||
/// Append a domain separator for an `n`-bit rangeproof for ElGamalKeypair
|
/// Append a domain separator for an `n`-bit rangeproof for ElGamalKeypair
|
||||||
/// ciphertext using a decryption key
|
/// ciphertext using a decryption key // TODO: remove?
|
||||||
fn rangeproof_from_key_domain_sep(&mut self, n: u64);
|
fn rangeproof_from_key_domain_sep(&mut self, n: u64);
|
||||||
|
|
||||||
/// Append a domain separator for an `n`-bit rangeproof for ElGamalKeypair
|
/// Append a domain separator for an `n`-bit rangeproof for ElGamalKeypair
|
||||||
/// ciphertext using an opening
|
/// ciphertext using an opening // TODO: remove?
|
||||||
fn rangeproof_from_opening_domain_sep(&mut self, n: u64);
|
fn rangeproof_from_opening_domain_sep(&mut self, n: u64);
|
||||||
|
|
||||||
/// Append a domain separator for a length-`n` inner product proof.
|
/// Append a domain separator for a length-`n` inner product proof.
|
||||||
|
@ -19,17 +19,11 @@ pub trait TranscriptProtocol {
|
||||||
/// Append a domain separator for close account proof.
|
/// Append a domain separator for close account proof.
|
||||||
fn close_account_proof_domain_sep(&mut self);
|
fn close_account_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for update account public key proof.
|
|
||||||
fn update_account_public_key_proof_domain_sep(&mut self);
|
|
||||||
|
|
||||||
/// Append a domain separator for withdraw proof.
|
/// Append a domain separator for withdraw proof.
|
||||||
fn withdraw_proof_domain_sep(&mut self);
|
fn withdraw_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for transfer with range proof.
|
/// Append a domain separator for transfer proof.
|
||||||
fn transfer_range_proof_sep(&mut self);
|
fn transfer_proof_domain_sep(&mut self);
|
||||||
|
|
||||||
/// Append a domain separator for transfer with validity proof.
|
|
||||||
fn transfer_validity_proof_sep(&mut self);
|
|
||||||
|
|
||||||
/// Append a `scalar` with the given `label`.
|
/// Append a `scalar` with the given `label`.
|
||||||
fn append_scalar(&mut self, label: &'static [u8], scalar: &Scalar);
|
fn append_scalar(&mut self, label: &'static [u8], scalar: &Scalar);
|
||||||
|
@ -69,20 +63,12 @@ impl TranscriptProtocol for Transcript {
|
||||||
self.append_message(b"dom_sep", b"CloseAccountProof");
|
self.append_message(b"dom_sep", b"CloseAccountProof");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_account_public_key_proof_domain_sep(&mut self) {
|
|
||||||
self.append_message(b"dom_sep", b"UpdateAccountPublicKeyProof");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn withdraw_proof_domain_sep(&mut self) {
|
fn withdraw_proof_domain_sep(&mut self) {
|
||||||
self.append_message(b"dom_sep", b"WithdrawProof");
|
self.append_message(b"dom_sep", b"WithdrawProof");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer_range_proof_sep(&mut self) {
|
fn transfer_proof_domain_sep(&mut self) {
|
||||||
self.append_message(b"dom_sep", b"TransferRangeProof");
|
self.append_message(b"dom_sep", b"TransferProof");
|
||||||
}
|
|
||||||
|
|
||||||
fn transfer_validity_proof_sep(&mut self) {
|
|
||||||
self.append_message(b"dom_sep", b"TransferValidityProof");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_scalar(&mut self, label: &'static [u8], scalar: &Scalar) {
|
fn append_scalar(&mut self, label: &'static [u8], scalar: &Scalar) {
|
||||||
|
|
Loading…
Reference in New Issue