zebra_chain/sapling/note/
ciphertexts.rs

1//! Encrypted parts of Sapling notes.
2
3use std::{fmt, io};
4
5use serde_big_array::BigArray;
6
7use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
8
9/// A ciphertext component for encrypted output notes.
10///
11/// Corresponds to the Sapling 'encCiphertext's
12#[derive(Deserialize, Serialize)]
13pub struct EncryptedNote(#[serde(with = "BigArray")] pub(crate) [u8; 580]);
14
15impl From<[u8; 580]> for EncryptedNote {
16    fn from(byte_array: [u8; 580]) -> Self {
17        Self(byte_array)
18    }
19}
20
21impl fmt::Debug for EncryptedNote {
22    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23        f.debug_tuple("EncryptedNote")
24            .field(&hex::encode(&self.0[..]))
25            .finish()
26    }
27}
28
29// These impls all only exist because of array length restrictions.
30
31impl Copy for EncryptedNote {}
32
33impl Clone for EncryptedNote {
34    fn clone(&self) -> Self {
35        *self
36    }
37}
38
39impl PartialEq for EncryptedNote {
40    fn eq(&self, other: &Self) -> bool {
41        self.0[..] == other.0[..]
42    }
43}
44
45impl Eq for EncryptedNote {}
46
47impl ZcashSerialize for EncryptedNote {
48    fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
49        writer.write_all(&self.0[..])?;
50        Ok(())
51    }
52}
53
54impl ZcashDeserialize for EncryptedNote {
55    fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
56        let mut bytes = [0; 580];
57        reader.read_exact(&mut bytes[..])?;
58        Ok(Self(bytes))
59    }
60}
61
62impl From<EncryptedNote> for [u8; 580] {
63    fn from(note: EncryptedNote) -> Self {
64        note.0
65    }
66}
67
68/// A ciphertext component for encrypted output notes.
69///
70/// Corresponds to Sapling's 'outCiphertext'
71#[derive(Deserialize, Serialize)]
72pub struct WrappedNoteKey(#[serde(with = "BigArray")] pub(crate) [u8; 80]);
73
74impl From<[u8; 80]> for WrappedNoteKey {
75    fn from(byte_array: [u8; 80]) -> Self {
76        Self(byte_array)
77    }
78}
79
80impl fmt::Debug for WrappedNoteKey {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        f.debug_tuple("WrappedNoteKey")
83            .field(&hex::encode(&self.0[..]))
84            .finish()
85    }
86}
87
88// These impls all only exist because of array length restrictions.
89
90impl Copy for WrappedNoteKey {}
91
92impl Clone for WrappedNoteKey {
93    fn clone(&self) -> Self {
94        *self
95    }
96}
97
98impl PartialEq for WrappedNoteKey {
99    fn eq(&self, other: &Self) -> bool {
100        self.0[..] == other.0[..]
101    }
102}
103
104impl Eq for WrappedNoteKey {}
105
106impl ZcashSerialize for WrappedNoteKey {
107    fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
108        writer.write_all(&self.0[..])?;
109        Ok(())
110    }
111}
112
113impl ZcashDeserialize for WrappedNoteKey {
114    fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
115        let mut bytes = [0; 80];
116        reader.read_exact(&mut bytes[..])?;
117        Ok(Self(bytes))
118    }
119}
120
121impl From<WrappedNoteKey> for [u8; 80] {
122    fn from(note: WrappedNoteKey) -> Self {
123        note.0
124    }
125}
126
127#[cfg(test)]
128use proptest::prelude::*;
129#[cfg(test)]
130proptest! {
131
132    #[test]
133    fn encrypted_ciphertext_roundtrip(ec in any::<EncryptedNote>()) {
134        let _init_guard = zebra_test::init();
135
136        let mut data = Vec::new();
137
138        ec.zcash_serialize(&mut data).expect("EncryptedNote should serialize");
139
140        let ec2 = EncryptedNote::zcash_deserialize(&data[..]).expect("randomized EncryptedNote should deserialize");
141
142        prop_assert_eq![ec, ec2];
143    }
144
145    #[test]
146    fn out_ciphertext_roundtrip(oc in any::<WrappedNoteKey>()) {
147        let _init_guard = zebra_test::init();
148
149        let mut data = Vec::new();
150
151        oc.zcash_serialize(&mut data).expect("WrappedNoteKey should serialize");
152
153        let oc2 = WrappedNoteKey::zcash_deserialize(&data[..]).expect("randomized WrappedNoteKey should deserialize");
154
155        prop_assert_eq![oc, oc2];
156    }
157}