snarkvm_circuit_program/data/record/helpers/
owner.rs1use crate::{Ciphertext, Entry, Literal, Plaintext, Visibility};
17use snarkvm_circuit_network::Aleo;
18use snarkvm_circuit_types::{Address, Boolean, Field, environment::prelude::*};
19
20#[derive(Clone)]
22pub enum Owner<A: Aleo, Private: Visibility<A>> {
23 Public(Address<A>),
25 Private(Private),
27}
28
29#[cfg(feature = "console")]
30impl<A: Aleo> Inject for Owner<A, Plaintext<A>> {
31 type Primitive = console::Owner<A::Network, console::Plaintext<A::Network>>;
32
33 fn new(_: Mode, owner: Self::Primitive) -> Self {
35 match owner {
36 console::Owner::Public(owner) => Self::Public(Address::new(Mode::Private, owner)),
37 console::Owner::Private(console::Plaintext::Literal(console::Literal::Address(owner), ..)) => {
38 Self::Private(Plaintext::Literal(
39 Literal::Address(Address::new(Mode::Private, owner)),
40 Default::default(),
41 ))
42 }
43 _ => A::halt("Owner::<Plaintext>::new: Invalid primitive type for owner"),
44 }
45 }
46}
47
48#[cfg(feature = "console")]
49impl<A: Aleo> Inject for Owner<A, Ciphertext<A>> {
50 type Primitive = console::Owner<A::Network, console::Ciphertext<A::Network>>;
51
52 fn new(_: Mode, owner: Self::Primitive) -> Self {
54 match owner {
55 console::Owner::Public(owner) => Self::Public(Address::new(Mode::Private, owner)),
56 console::Owner::Private(ciphertext) => Self::Private(Ciphertext::new(Mode::Private, ciphertext)),
57 }
58 }
59}
60
61impl<A: Aleo> Deref for Owner<A, Plaintext<A>> {
62 type Target = Address<A>;
63
64 fn deref(&self) -> &Self::Target {
66 match self {
67 Self::Public(public) => public,
68 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address,
69 _ => A::halt("Internal error: plaintext deref corrupted in record owner"),
70 }
71 }
72}
73
74impl<A: Aleo, Private: Visibility<A>> Owner<A, Private> {
75 pub fn is_public(&self) -> Boolean<A> {
77 Boolean::constant(matches!(self, Self::Public(..)))
78 }
79
80 pub fn is_private(&self) -> Boolean<A> {
82 Boolean::constant(matches!(self, Self::Private(..)))
83 }
84}
85
86impl<A: Aleo> Owner<A, Plaintext<A>> {
87 pub fn to_entry(&self) -> Entry<A, Plaintext<A>> {
89 match self {
90 Self::Public(owner) => Entry::Public(Plaintext::from(Literal::Address(owner.clone()))),
91 Self::Private(plaintext, ..) => Entry::Private(plaintext.clone()),
92 }
93 }
94}
95
96impl<A: Aleo, Private: Visibility<A>> Equal<Self> for Owner<A, Private> {
97 type Output = Boolean<A>;
98
99 fn is_equal(&self, other: &Self) -> Self::Output {
101 match (self, other) {
102 (Self::Public(a), Self::Public(b)) => a.is_equal(b),
103 (Self::Private(a), Self::Private(b)) => a.is_equal(b),
104 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::constant(false),
105 }
106 }
107
108 fn is_not_equal(&self, other: &Self) -> Self::Output {
110 match (self, other) {
111 (Self::Public(a), Self::Public(b)) => a.is_not_equal(b),
112 (Self::Private(a), Self::Private(b)) => a.is_not_equal(b),
113 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::constant(true),
114 }
115 }
116}
117
118impl<A: Aleo> Owner<A, Plaintext<A>> {
119 pub fn encrypt(&self, randomizer: &[Field<A>]) -> Owner<A, Ciphertext<A>> {
121 match self {
122 Self::Public(public) => {
123 if !randomizer.is_empty() {
125 A::halt(format!("Expected 0 randomizers, found {}", randomizer.len()))
126 }
127 Owner::Public(public.clone())
129 }
130 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => {
131 if randomizer.len() != 1 {
133 A::halt(format!("Expected 1 randomizer, found {}", randomizer.len()))
134 }
135 let ciphertext = address.to_field() + &randomizer[0];
137 Owner::Private(Ciphertext::from_fields(&[ciphertext]))
139 }
140 _ => A::halt("Internal error: plaintext encryption corrupted in record owner"),
141 }
142 }
143}
144
145impl<A: Aleo> Owner<A, Ciphertext<A>> {
146 pub fn decrypt(&self, randomizer: &[Field<A>]) -> Owner<A, Plaintext<A>> {
148 match self {
149 Self::Public(public) => {
150 if !randomizer.is_empty() {
152 A::halt(format!("Expected 0 randomizers, found {}", randomizer.len()))
153 }
154 Owner::Public(public.clone())
156 }
157 Self::Private(ciphertext) => {
158 if randomizer.len() != 1 {
160 A::halt(format!("Expected 1 randomizer, found {}", randomizer.len()))
161 }
162 if ciphertext.len() != 1 {
164 A::halt(format!("Expected 1 ciphertext, found {}", ciphertext.len()))
165 }
166 let owner = Address::from_field(&ciphertext[0] - &randomizer[0]);
168 Owner::Private(Plaintext::from(Literal::Address(owner)))
170 }
171 }
172 }
173}
174
175impl<A: Aleo> ToBits for Owner<A, Plaintext<A>> {
176 type Boolean = Boolean<A>;
177
178 fn write_bits_le(&self, vec: &mut Vec<Boolean<A>>) {
180 vec.push(self.is_private());
181 match self {
182 Self::Public(public) => public.write_bits_le(vec),
183 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_le(vec),
184 _ => A::halt("Internal error: plaintext to_bits_le corrupted in record owner"),
185 };
186 }
187
188 fn write_bits_be(&self, vec: &mut Vec<Boolean<A>>) {
190 vec.push(self.is_private());
191 match self {
192 Self::Public(public) => public.write_bits_be(vec),
193 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_be(vec),
194 _ => A::halt("Internal error: plaintext to_bits_be corrupted in record owner"),
195 };
196 }
197}
198
199impl<A: Aleo> ToBits for Owner<A, Ciphertext<A>> {
200 type Boolean = Boolean<A>;
201
202 fn write_bits_le(&self, vec: &mut Vec<Boolean<A>>) {
204 vec.push(self.is_private());
205 match self {
206 Self::Public(public) => public.write_bits_le(vec),
207 Self::Private(ciphertext) => {
208 match ciphertext.len() == 1 {
210 true => ciphertext[0].write_bits_le(vec),
211 false => A::halt("Internal error: ciphertext to_bits_le corrupted in record owner"),
212 }
213 }
214 };
215 }
216
217 fn write_bits_be(&self, vec: &mut Vec<Boolean<A>>) {
219 vec.push(self.is_private());
220 match self {
221 Self::Public(public) => public.write_bits_be(vec),
222 Self::Private(ciphertext) => {
223 match ciphertext.len() == 1 {
225 true => ciphertext[0].write_bits_be(vec),
226 false => A::halt("Internal error: ciphertext to_bits_be corrupted in record owner"),
227 }
228 }
229 };
230 }
231}