snarkvm_console_program/data/record/helpers/
owner.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use crate::{Ciphertext, Entry, Literal, Plaintext};
17use snarkvm_console_network::prelude::*;
18use snarkvm_console_types::{Address, Boolean, Field};
19
20/// A value stored in program data.
21#[derive(Clone)]
22pub enum Owner<N: Network, Private: Visibility> {
23    /// A publicly-visible value.
24    Public(Address<N>),
25    /// A private value is encrypted under the account owner's address.
26    Private(Private),
27}
28
29impl<N: Network> Deref for Owner<N, Plaintext<N>> {
30    type Target = Address<N>;
31
32    /// Returns the address of the owner.
33    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    /// Returns `true` if `self` is public.
44    pub const fn is_public(&self) -> bool {
45        matches!(self, Self::Public(..))
46    }
47
48    /// Returns `true` if `self` is private.
49    pub const fn is_private(&self) -> bool {
50        matches!(self, Self::Private(..))
51    }
52}
53
54impl<N: Network> Owner<N, Plaintext<N>> {
55    /// Returns the owner as an `Entry`.
56    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    /// Returns `true` if `self` and `other` are equal.
68    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    /// Returns `true` if `self` and `other` are equal.
77    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    /// Returns `true` if `self` and `other` are *not* equal.
86    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    /// Encrypts `self` under the given randomizer.
97    pub fn encrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Ciphertext<N>>> {
98        match self {
99            Self::Public(public) => {
100                // Ensure there is exactly zero randomizers.
101                ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len());
102                // Return the owner.
103                Ok(Owner::Public(*public))
104            }
105            Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => {
106                // Ensure there is exactly one randomizer.
107                ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len());
108                // Encrypt the owner.
109                let ciphertext = address.to_field()? + randomizer[0];
110                // Return the encrypted owner.
111                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    /// Decrypts the owner under the given randomizer.
120    pub fn decrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Plaintext<N>>> {
121        match self {
122            Self::Public(public) => {
123                // Ensure there is exactly zero randomizers.
124                ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len());
125                // Return the owner.
126                Ok(Owner::Public(*public))
127            }
128            Self::Private(ciphertext) => {
129                // Ensure there is exactly one randomizer.
130                ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len());
131                // Ensure there is exactly one field element in the ciphertext.
132                ensure!(ciphertext.len() == 1, "Expected 1 ciphertext, found {}", ciphertext.len());
133                // Decrypt the owner.
134                let owner = Address::from_field(&(ciphertext[0] - randomizer[0]))?;
135                // Return the owner.
136                Ok(Owner::Private(Plaintext::from(Literal::Address(owner))))
137            }
138        }
139    }
140}
141
142impl<N: Network> ToBits for Owner<N, Plaintext<N>> {
143    /// Returns `self` as a boolean vector in little-endian order.
144    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    /// Returns `self` as a boolean vector in big-endian order.
154    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    /// Returns `self` as a boolean vector in little-endian order.
166    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                // Ensure there is exactly one field element in the ciphertext.
172                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    /// Returns `self` as a boolean vector in big-endian order.
181    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                // Ensure there is exactly one field element in the ciphertext.
187                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    /// Prints the owner as a string.
198    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    /// Prints the owner as a string, i.e. `aleo1xxx.public`.
205    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    /// Reads the owner from a buffer.
216    fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
217        // Read the index.
218        let index = u8::read_le(&mut reader)?;
219        // Read the owner.
220        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    /// Writes the owner to a buffer.
231    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}