zebra_chain/orchard/note/
ciphertexts.rs

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