Refine JoinSplit ephemeral keys to be x25519_dalek::PublicKey
Impls PartialEq and Eq and Arbitrary on JoinSplit because PublicKey does not impl them and we can't do it directly. Resolves #313
This commit is contained in:
parent
baf305b856
commit
05ca1c0c8a
|
|
@ -16,8 +16,7 @@ use crate::{
|
||||||
/// A _JoinSplit Description_, as described in [protocol specification §7.2][ps].
|
/// A _JoinSplit Description_, as described in [protocol specification §7.2][ps].
|
||||||
///
|
///
|
||||||
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#joinsplitencoding
|
/// [ps]: https://zips.z.cash/protocol/protocol.pdf#joinsplitencoding
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(test, derive(Arbitrary))]
|
|
||||||
pub struct JoinSplit<P: ZkSnarkProof> {
|
pub struct JoinSplit<P: ZkSnarkProof> {
|
||||||
/// A value that the JoinSplit transfer removes from the transparent value
|
/// A value that the JoinSplit transfer removes from the transparent value
|
||||||
/// pool.
|
/// pool.
|
||||||
|
|
@ -46,7 +45,7 @@ pub struct JoinSplit<P: ZkSnarkProof> {
|
||||||
/// An X25519 public key.
|
/// An X25519 public key.
|
||||||
///
|
///
|
||||||
/// XXX refine to an x25519-dalek type?
|
/// 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
|
/// A 256-bit seed that must be chosen independently at random for each
|
||||||
/// JoinSplit description.
|
/// JoinSplit description.
|
||||||
pub random_seed: [u8; 32],
|
pub random_seed: [u8; 32],
|
||||||
|
|
@ -62,8 +61,77 @@ pub struct JoinSplit<P: ZkSnarkProof> {
|
||||||
pub enc_ciphertexts: [EncryptedCiphertext; 2],
|
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.
|
/// A bundle of JoinSplit descriptions and signature data.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct JoinSplitData<P: ZkSnarkProof> {
|
pub struct JoinSplitData<P: ZkSnarkProof> {
|
||||||
/// The first JoinSplit description, using proofs of type `P`.
|
/// The first JoinSplit description, using proofs of type `P`.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ impl<P: ZkSnarkProof> ZcashSerialize for JoinSplit<P> {
|
||||||
writer.write_all(&self.nullifiers[1][..])?;
|
writer.write_all(&self.nullifiers[1][..])?;
|
||||||
writer.write_all(&self.commitments[0][..])?;
|
writer.write_all(&self.commitments[0][..])?;
|
||||||
writer.write_all(&self.commitments[1][..])?;
|
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.random_seed[..])?;
|
||||||
writer.write_all(&self.vmacs[0][..])?;
|
writer.write_all(&self.vmacs[0][..])?;
|
||||||
writer.write_all(&self.vmacs[1][..])?;
|
writer.write_all(&self.vmacs[1][..])?;
|
||||||
|
|
@ -254,7 +254,7 @@ impl<P: ZkSnarkProof> ZcashDeserialize for JoinSplit<P> {
|
||||||
anchor: reader.read_32_bytes()?,
|
anchor: reader.read_32_bytes()?,
|
||||||
nullifiers: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
nullifiers: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
||||||
commitments: [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()?,
|
random_seed: reader.read_32_bytes()?,
|
||||||
vmacs: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
vmacs: [reader.read_32_bytes()?, reader.read_32_bytes()?],
|
||||||
zkproof: P::zcash_deserialize(&mut reader)?,
|
zkproof: P::zcash_deserialize(&mut reader)?,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue