zebra_chain/sprout/note/
mac.rs

1//! Sprout message authentication codes.
2
3use std::io::{self, Read};
4
5use crate::{
6    fmt::HexDebug,
7    serialization::{ReadZcashExt, SerializationError, ZcashDeserialize, ZcashSerialize},
8};
9
10/// A sequence of message authentication tags ...
11///
12/// binding h_sig to each a_sk of the JoinSplit description, computed as
13/// described in ยง 4.10 'Non-malleability (Sprout)' on p. 37
14#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
15#[cfg_attr(
16    any(test, feature = "proptest-impl"),
17    derive(proptest_derive::Arbitrary)
18)]
19pub struct Mac(HexDebug<[u8; 32]>);
20
21impl Mac {
22    /// Return the bytes in big-endian byte order as required
23    /// by RPCs such as `getrawtransaction`.
24    pub fn bytes_in_display_order(&self) -> [u8; 32] {
25        let mut root: [u8; 32] = self.into();
26        root.reverse();
27        root
28    }
29}
30
31impl From<[u8; 32]> for Mac {
32    fn from(bytes: [u8; 32]) -> Self {
33        Self(bytes.into())
34    }
35}
36
37impl From<Mac> for [u8; 32] {
38    fn from(rt: Mac) -> [u8; 32] {
39        *rt.0
40    }
41}
42
43impl From<&Mac> for [u8; 32] {
44    fn from(mac: &Mac) -> Self {
45        mac.clone().into()
46    }
47}
48
49impl ZcashDeserialize for Mac {
50    fn zcash_deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
51        let bytes = reader.read_32_bytes()?;
52
53        Ok(Self(bytes.into()))
54    }
55}
56
57impl ZcashSerialize for Mac {
58    fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
59        writer.write_all(&self.0[..])
60    }
61}