Skip to content

Commit

Permalink
Refine JoinSplit ephemeral keys to be x25519_dalek::PublicKey
Browse files Browse the repository at this point in the history
Impls PartialEq and Eq and Arbitrary on JoinSplit because PublicKey
does not impl them and we can't do it directly.

Resolves #313
  • Loading branch information
dconnolly committed Apr 13, 2020
1 parent baf305b commit 05ca1c0
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 6 deletions.
76 changes: 72 additions & 4 deletions zebra-chain/src/transaction/joinsplit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use crate::{
/// A _JoinSplit Description_, as described in [protocol specification §7.2][ps].
///
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#joinsplitencoding
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(test, derive(Arbitrary))]
#[derive(Clone, Debug)]
pub struct JoinSplit<P: ZkSnarkProof> {
/// A value that the JoinSplit transfer removes from the transparent value
/// pool.
Expand Down Expand Up @@ -46,7 +45,7 @@ pub struct JoinSplit<P: ZkSnarkProof> {
/// An X25519 public key.
///
/// XXX refine to an x25519-dalek type?
pub ephemeral_key: [u8; 32],
pub ephemeral_key: x25519_dalek::PublicKey,
/// A 256-bit seed that must be chosen independently at random for each
/// JoinSplit description.
pub random_seed: [u8; 32],
Expand All @@ -62,8 +61,77 @@ pub struct JoinSplit<P: ZkSnarkProof> {
pub enc_ciphertexts: [EncryptedCiphertext; 2],
}

// Because x25519_dalek::PublicKey does not impl PartialEq
impl<P: ZkSnarkProof> PartialEq for JoinSplit<P> {
fn eq(&self, other: &Self) -> bool {
self.vpub_old == other.vpub_old
&& self.vpub_new == other.vpub_new
&& self.anchor == other.anchor
&& self.nullifiers == other.nullifiers
&& self.commitments == other.commitments
&& self.ephemeral_key.as_bytes() == other.ephemeral_key.as_bytes()
&& self.random_seed == other.random_seed
&& self.vmacs == other.vmacs
&& self.zkproof == other.zkproof
&& self.enc_ciphertexts == other.enc_ciphertexts
}
}

// Because x25519_dalek::PublicKey does not impl Eq
impl<P: ZkSnarkProof> Eq for JoinSplit<P> {}

#[cfg(test)]
impl<P: ZkSnarkProof + Arbitrary + 'static> Arbitrary for JoinSplit<P> {
type Parameters = ();

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(
any::<u64>(),
any::<u64>(),
array::uniform32(any::<u8>()),
array::uniform2(array::uniform32(any::<u8>())),
array::uniform2(array::uniform32(any::<u8>())),
array::uniform32(any::<u8>()),
array::uniform32(any::<u8>()),
array::uniform2(array::uniform32(any::<u8>())),
any::<P>(),
array::uniform2(any::<EncryptedCiphertext>()),
)
.prop_map(
|(
vpub_old,
vpub_new,
anchor,
nullifiers,
commitments,
ephemeral_key_bytes,
random_seed,
vmacs,
zkproof,
enc_ciphertexts,
)| {
return Self {
vpub_old,
vpub_new,
anchor,
nullifiers,
commitments,
ephemeral_key: x25519_dalek::PublicKey::from(ephemeral_key_bytes),
random_seed,
vmacs,
zkproof,
enc_ciphertexts,
};
},
)
.boxed()
}

type Strategy = BoxedStrategy<Self>;
}

/// A bundle of JoinSplit descriptions and signature data.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct JoinSplitData<P: ZkSnarkProof> {
/// The first JoinSplit description, using proofs of type `P`.
///
Expand Down
4 changes: 2 additions & 2 deletions zebra-chain/src/transaction/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl<P: ZkSnarkProof> ZcashSerialize for JoinSplit<P> {
writer.write_all(&self.nullifiers[1][..])?;
writer.write_all(&self.commitments[0][..])?;
writer.write_all(&self.commitments[1][..])?;
writer.write_all(&self.ephemeral_key[..])?;
writer.write_all(&self.ephemeral_key.as_bytes()[..])?;
writer.write_all(&self.random_seed[..])?;
writer.write_all(&self.vmacs[0][..])?;
writer.write_all(&self.vmacs[1][..])?;
Expand All @@ -254,7 +254,7 @@ impl<P: ZkSnarkProof> ZcashDeserialize for JoinSplit<P> {
anchor: reader.read_32_bytes()?,
nullifiers: [reader.read_32_bytes()?, reader.read_32_bytes()?],
commitments: [reader.read_32_bytes()?, reader.read_32_bytes()?],
ephemeral_key: reader.read_32_bytes()?,
ephemeral_key: x25519_dalek::PublicKey::from(reader.read_32_bytes()?),
random_seed: reader.read_32_bytes()?,
vmacs: [reader.read_32_bytes()?, reader.read_32_bytes()?],
zkproof: P::zcash_deserialize(&mut reader)?,
Expand Down

0 comments on commit 05ca1c0

Please sign in to comment.