From c216f5ca257882b34274667dac66bd55c023473e Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 1 Jul 2020 17:57:03 -0700 Subject: [PATCH] Refine type for MAC (#577) --- zebra-chain/src/transaction/joinsplit.rs | 4 +- zebra-chain/src/transaction/serialize.rs | 9 +++-- .../src/transaction/tests/arbitrary.rs | 2 +- zebra-chain/src/types.rs | 40 +++++++++++++------ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/zebra-chain/src/transaction/joinsplit.rs b/zebra-chain/src/transaction/joinsplit.rs index 15814366b..8ce679e84 100644 --- a/zebra-chain/src/transaction/joinsplit.rs +++ b/zebra-chain/src/transaction/joinsplit.rs @@ -34,9 +34,7 @@ pub struct JoinSplit { /// JoinSplit description. pub random_seed: [u8; 32], /// A message authentication tag. - /// - /// XXX refine type to [T; 2] -- there are two macs - pub vmacs: [[u8; 32]; 2], + pub vmacs: [crate::types::MAC; 2], /// A ZK JoinSplit proof, either a /// [`Groth16Proof`](crate::proofs::Groth16Proof) or a /// [`Bctv14Proof`](crate::proofs::Bctv14Proof). diff --git a/zebra-chain/src/transaction/serialize.rs b/zebra-chain/src/transaction/serialize.rs index 666375e3c..d49e7a6fb 100644 --- a/zebra-chain/src/transaction/serialize.rs +++ b/zebra-chain/src/transaction/serialize.rs @@ -242,8 +242,8 @@ impl ZcashSerialize for JoinSplit

{ writer.write_all(&self.commitments[1][..])?; 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][..])?; + self.vmacs[0].zcash_serialize(&mut writer)?; + self.vmacs[1].zcash_serialize(&mut writer)?; self.zkproof.zcash_serialize(&mut writer)?; self.enc_ciphertexts[0].zcash_serialize(&mut writer)?; self.enc_ciphertexts[1].zcash_serialize(&mut writer)?; @@ -261,7 +261,10 @@ impl ZcashDeserialize for JoinSplit

{ commitments: [reader.read_32_bytes()?, 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()?], + vmacs: [ + crate::types::MAC::zcash_deserialize(&mut reader)?, + crate::types::MAC::zcash_deserialize(&mut reader)?, + ], zkproof: P::zcash_deserialize(&mut reader)?, enc_ciphertexts: [ notes::sprout::EncryptedCiphertext::zcash_deserialize(&mut reader)?, diff --git a/zebra-chain/src/transaction/tests/arbitrary.rs b/zebra-chain/src/transaction/tests/arbitrary.rs index 0340389b0..3e40dda4a 100644 --- a/zebra-chain/src/transaction/tests/arbitrary.rs +++ b/zebra-chain/src/transaction/tests/arbitrary.rs @@ -26,7 +26,7 @@ impl Arbitrary for JoinSplit

{ array::uniform2(array::uniform32(any::())), array::uniform32(any::()), array::uniform32(any::()), - array::uniform2(array::uniform32(any::())), + array::uniform2(any::()), any::

(), array::uniform2(any::()), ) diff --git a/zebra-chain/src/types.rs b/zebra-chain/src/types.rs index fde98a026..81e803fb2 100644 --- a/zebra-chain/src/types.rs +++ b/zebra-chain/src/types.rs @@ -1,20 +1,15 @@ //! Newtype wrappers for primitive data types with semantic meaning. - +#![allow(clippy::unit_arg)] +use crate::serialization::{ + ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, +}; +use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; +use chrono::{DateTime, TimeZone, Utc}; use std::{ fmt, io::{self, Read}, }; -use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use chrono::{DateTime, TimeZone, Utc}; - -#[cfg(test)] -use proptest_derive::Arbitrary; - -use crate::serialization::{ - ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize, -}; - pub mod amount; /// A u32 which represents a block height value. @@ -93,9 +88,30 @@ impl Arbitrary for LockTime { type Strategy = BoxedStrategy; } +/// A sequence of message authentication tags ... +/// +/// binding h_sig to each a_sk of the JoinSplit description, computed as +/// described in § 4.10 ‘Non-malleability (Sprout)’ on p. 37 +#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(proptest_derive::Arbitrary))] +pub struct MAC([u8; 32]); + +impl ZcashDeserialize for MAC { + fn zcash_deserialize(mut reader: R) -> Result { + let bytes = reader.read_32_bytes()?; + + Ok(Self(bytes)) + } +} + +impl ZcashSerialize for MAC { + fn zcash_serialize(&self, mut writer: W) -> Result<(), io::Error> { + writer.write_all(&self.0[..]) + } +} /// An encoding of a Bitcoin script. #[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] -#[cfg_attr(test, derive(Arbitrary))] +#[cfg_attr(test, derive(proptest_derive::Arbitrary))] pub struct Script(pub Vec); impl fmt::Debug for Script {