snarkvm_console_program/data/record/helpers/
owner.rs1use crate::{Ciphertext, Entry, Literal, Plaintext};
17use snarkvm_console_network::prelude::*;
18use snarkvm_console_types::{Address, Boolean, Field};
19
20#[derive(Clone)]
22pub enum Owner<N: Network, Private: Visibility> {
23 Public(Address<N>),
25 Private(Private),
27}
28
29impl<N: Network> Deref for Owner<N, Plaintext<N>> {
30 type Target = Address<N>;
31
32 fn deref(&self) -> &Self::Target {
34 match self {
35 Self::Public(public) => public,
36 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address,
37 _ => N::halt("Internal error: plaintext deref corrupted in record owner"),
38 }
39 }
40}
41
42impl<N: Network, Private: Visibility> Owner<N, Private> {
43 pub const fn is_public(&self) -> bool {
45 matches!(self, Self::Public(..))
46 }
47
48 pub const fn is_private(&self) -> bool {
50 matches!(self, Self::Private(..))
51 }
52}
53
54impl<N: Network> Owner<N, Plaintext<N>> {
55 pub fn to_entry(&self) -> Entry<N, Plaintext<N>> {
57 match self {
58 Self::Public(owner) => Entry::Public(Plaintext::from(Literal::Address(*owner))),
59 Self::Private(plaintext, ..) => Entry::Private(plaintext.clone()),
60 }
61 }
62}
63
64impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Eq for Owner<N, Private> {}
65
66impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> PartialEq for Owner<N, Private> {
67 fn eq(&self, other: &Self) -> bool {
69 *self.is_equal(other)
70 }
71}
72
73impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Equal<Self> for Owner<N, Private> {
74 type Output = Boolean<N>;
75
76 fn is_equal(&self, other: &Self) -> Self::Output {
78 match (self, other) {
79 (Self::Public(a), Self::Public(b)) => a.is_equal(b),
80 (Self::Private(a), Self::Private(b)) => a.is_equal(b),
81 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::new(false),
82 }
83 }
84
85 fn is_not_equal(&self, other: &Self) -> Self::Output {
87 match (self, other) {
88 (Self::Public(a), Self::Public(b)) => a.is_not_equal(b),
89 (Self::Private(a), Self::Private(b)) => a.is_not_equal(b),
90 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::new(true),
91 }
92 }
93}
94
95impl<N: Network> Owner<N, Plaintext<N>> {
96 pub fn encrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Ciphertext<N>>> {
98 match self {
99 Self::Public(public) => {
100 ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len());
102 Ok(Owner::Public(*public))
104 }
105 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => {
106 ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len());
108 let ciphertext = address.to_field()? + randomizer[0];
110 Ok(Owner::Private(Ciphertext::from_fields(&[ciphertext])?))
112 }
113 _ => bail!("Internal error: plaintext encryption corrupted in record owner"),
114 }
115 }
116}
117
118impl<N: Network> Owner<N, Ciphertext<N>> {
119 pub fn decrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Plaintext<N>>> {
121 match self {
122 Self::Public(public) => {
123 ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len());
125 Ok(Owner::Public(*public))
127 }
128 Self::Private(ciphertext) => {
129 ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len());
131 ensure!(ciphertext.len() == 1, "Expected 1 ciphertext, found {}", ciphertext.len());
133 let owner = Address::from_field(&(ciphertext[0] - randomizer[0]))?;
135 Ok(Owner::Private(Plaintext::from(Literal::Address(owner))))
137 }
138 }
139 }
140}
141
142impl<N: Network> ToBits for Owner<N, Plaintext<N>> {
143 fn write_bits_le(&self, vec: &mut Vec<bool>) {
145 vec.push(self.is_private());
146 match self {
147 Self::Public(public) => public.write_bits_le(vec),
148 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_le(vec),
149 _ => N::halt("Internal error: plaintext to_bits_le corrupted in record owner"),
150 };
151 }
152
153 fn write_bits_be(&self, vec: &mut Vec<bool>) {
155 vec.push(self.is_private());
156 match self {
157 Self::Public(public) => public.write_bits_be(vec),
158 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_be(vec),
159 _ => N::halt("Internal error: plaintext to_bits_be corrupted in record owner"),
160 };
161 }
162}
163
164impl<N: Network> ToBits for Owner<N, Ciphertext<N>> {
165 fn write_bits_le(&self, vec: &mut Vec<bool>) {
167 vec.push(self.is_private());
168 match self {
169 Self::Public(public) => public.write_bits_le(vec),
170 Self::Private(ciphertext) => {
171 match ciphertext.len() == 1 {
173 true => ciphertext[0].write_bits_le(vec),
174 false => N::halt("Internal error: ciphertext to_bits_le corrupted in record owner"),
175 }
176 }
177 };
178 }
179
180 fn write_bits_be(&self, vec: &mut Vec<bool>) {
182 vec.push(self.is_private());
183 match self {
184 Self::Public(public) => public.write_bits_be(vec),
185 Self::Private(ciphertext) => {
186 match ciphertext.len() == 1 {
188 true => ciphertext[0].write_bits_be(vec),
189 false => N::halt("Internal error: ciphertext to_bits_be corrupted in record owner"),
190 }
191 }
192 };
193 }
194}
195
196impl<N: Network> Debug for Owner<N, Plaintext<N>> {
197 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
199 Display::fmt(self, f)
200 }
201}
202
203impl<N: Network> Display for Owner<N, Plaintext<N>> {
204 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
206 match self {
207 Self::Public(owner) => write!(f, "{owner}.public"),
208 Self::Private(Plaintext::Literal(Literal::Address(owner), ..)) => write!(f, "{owner}.private"),
209 _ => N::halt("Internal error: plaintext fmt corrupted in record owner"),
210 }
211 }
212}
213
214impl<N: Network, Private: Visibility> FromBytes for Owner<N, Private> {
215 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
217 let index = u8::read_le(&mut reader)?;
219 let owner = match index {
221 0 => Self::Public(Address::read_le(&mut reader)?),
222 1 => Self::Private(Private::read_le(&mut reader)?),
223 2.. => return Err(error(format!("Failed to decode owner variant {index}"))),
224 };
225 Ok(owner)
226 }
227}
228
229impl<N: Network, Private: Visibility> ToBytes for Owner<N, Private> {
230 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
232 match self {
233 Self::Public(owner) => {
234 0u8.write_le(&mut writer)?;
235 owner.write_le(&mut writer)
236 }
237 Self::Private(owner) => {
238 1u8.write_le(&mut writer)?;
239 owner.write_le(&mut writer)
240 }
241 }
242 }
243}