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
29impl<A: Aleo> Inject for Owner<A, Plaintext<A>> {
30 type Primitive = console::Owner<A::Network, console::Plaintext<A::Network>>;
31
32 fn new(_: Mode, owner: Self::Primitive) -> Self {
34 match owner {
35 console::Owner::Public(owner) => Self::Public(Address::new(Mode::Private, owner)),
36 console::Owner::Private(console::Plaintext::Literal(console::Literal::Address(owner), ..)) => {
37 Self::Private(Plaintext::Literal(
38 Literal::Address(Address::new(Mode::Private, owner)),
39 Default::default(),
40 ))
41 }
42 _ => A::halt("Owner::<Plaintext>::new: Invalid primitive type for owner"),
43 }
44 }
45}
46
47impl<A: Aleo> Inject for Owner<A, Ciphertext<A>> {
48 type Primitive = console::Owner<A::Network, console::Ciphertext<A::Network>>;
49
50 fn new(_: Mode, owner: Self::Primitive) -> Self {
52 match owner {
53 console::Owner::Public(owner) => Self::Public(Address::new(Mode::Private, owner)),
54 console::Owner::Private(ciphertext) => Self::Private(Ciphertext::new(Mode::Private, ciphertext)),
55 }
56 }
57}
58
59impl<A: Aleo> Deref for Owner<A, Plaintext<A>> {
60 type Target = Address<A>;
61
62 fn deref(&self) -> &Self::Target {
64 match self {
65 Self::Public(public) => public,
66 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address,
67 _ => A::halt("Internal error: plaintext deref corrupted in record owner"),
68 }
69 }
70}
71
72impl<A: Aleo, Private: Visibility<A>> Owner<A, Private> {
73 pub fn is_public(&self) -> Boolean<A> {
75 Boolean::constant(matches!(self, Self::Public(..)))
76 }
77
78 pub fn is_private(&self) -> Boolean<A> {
80 Boolean::constant(matches!(self, Self::Private(..)))
81 }
82}
83
84impl<A: Aleo> Owner<A, Plaintext<A>> {
85 pub fn to_entry(&self) -> Entry<A, Plaintext<A>> {
87 match self {
88 Self::Public(owner) => Entry::Public(Plaintext::from(Literal::Address(owner.clone()))),
89 Self::Private(plaintext, ..) => Entry::Private(plaintext.clone()),
90 }
91 }
92}
93
94impl<A: Aleo, Private: Visibility<A>> Equal<Self> for Owner<A, Private> {
95 type Output = Boolean<A>;
96
97 fn is_equal(&self, other: &Self) -> Self::Output {
99 match (self, other) {
100 (Self::Public(a), Self::Public(b)) => a.is_equal(b),
101 (Self::Private(a), Self::Private(b)) => a.is_equal(b),
102 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::constant(false),
103 }
104 }
105
106 fn is_not_equal(&self, other: &Self) -> Self::Output {
108 match (self, other) {
109 (Self::Public(a), Self::Public(b)) => a.is_not_equal(b),
110 (Self::Private(a), Self::Private(b)) => a.is_not_equal(b),
111 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::constant(true),
112 }
113 }
114}
115
116impl<A: Aleo> Owner<A, Plaintext<A>> {
117 pub fn encrypt(&self, randomizer: &[Field<A>]) -> Owner<A, Ciphertext<A>> {
119 match self {
120 Self::Public(public) => {
121 if !randomizer.is_empty() {
123 A::halt(format!("Expected 0 randomizers, found {}", randomizer.len()))
124 }
125 Owner::Public(public.clone())
127 }
128 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => {
129 if randomizer.len() != 1 {
131 A::halt(format!("Expected 1 randomizer, found {}", randomizer.len()))
132 }
133 let ciphertext = address.to_field() + &randomizer[0];
135 Owner::Private(Ciphertext::from_fields(&[ciphertext]))
137 }
138 _ => A::halt("Internal error: plaintext encryption corrupted in record owner"),
139 }
140 }
141}
142
143impl<A: Aleo> Owner<A, Ciphertext<A>> {
144 pub fn decrypt(&self, randomizer: &[Field<A>]) -> Owner<A, Plaintext<A>> {
146 match self {
147 Self::Public(public) => {
148 if !randomizer.is_empty() {
150 A::halt(format!("Expected 0 randomizers, found {}", randomizer.len()))
151 }
152 Owner::Public(public.clone())
154 }
155 Self::Private(ciphertext) => {
156 if randomizer.len() != 1 {
158 A::halt(format!("Expected 1 randomizer, found {}", randomizer.len()))
159 }
160 if ciphertext.len() != 1 {
162 A::halt(format!("Expected 1 ciphertext, found {}", ciphertext.len()))
163 }
164 let owner = Address::from_field(&ciphertext[0] - &randomizer[0]);
166 Owner::Private(Plaintext::from(Literal::Address(owner)))
168 }
169 }
170 }
171}