owner.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm 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 16 use crate::{Ciphertext, Entry, Literal, Plaintext}; 17 use alphavm_console_network::prelude::*; 18 use alphavm_console_types::{Address, Boolean, Field}; 19 20 /// A value stored in program data. 21 #[derive(Clone)] 22 pub 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 29 impl<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 42 impl<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 54 impl<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 64 impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Eq for Owner<N, Private> {} 65 66 impl<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 73 impl<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 95 impl<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 118 impl<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 142 impl<N: Network> Debug for Owner<N, Plaintext<N>> { 143 /// Prints the owner as a string. 144 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 145 Display::fmt(self, f) 146 } 147 } 148 149 impl<N: Network> Display for Owner<N, Plaintext<N>> { 150 /// Prints the owner as a string, i.e. `ax1xxx.public`. 151 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 152 match self { 153 Self::Public(owner) => write!(f, "{owner}.public"), 154 Self::Private(Plaintext::Literal(Literal::Address(owner), ..)) => write!(f, "{owner}.private"), 155 _ => N::halt("Internal error: plaintext fmt corrupted in record owner"), 156 } 157 } 158 }