owner.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use crate::{Ciphertext, Entry, Literal, Plaintext}; 20 use alphavm_console_network::prelude::*; 21 use alphavm_console_types::{Address, Boolean, Field}; 22 23 /// A value stored in program data. 24 #[derive(Clone)] 25 pub enum Owner<N: Network, Private: Visibility> { 26 /// A publicly-visible value. 27 Public(Address<N>), 28 /// A private value is encrypted under the account owner's address. 29 Private(Private), 30 } 31 32 impl<N: Network> Deref for Owner<N, Plaintext<N>> { 33 type Target = Address<N>; 34 35 /// Returns the address of the owner. 36 fn deref(&self) -> &Self::Target { 37 match self { 38 Self::Public(public) => public, 39 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => address, 40 _ => N::halt("Internal error: plaintext deref corrupted in record owner"), 41 } 42 } 43 } 44 45 impl<N: Network, Private: Visibility> Owner<N, Private> { 46 /// Returns `true` if `self` is public. 47 pub const fn is_public(&self) -> bool { 48 matches!(self, Self::Public(..)) 49 } 50 51 /// Returns `true` if `self` is private. 52 pub const fn is_private(&self) -> bool { 53 matches!(self, Self::Private(..)) 54 } 55 } 56 57 impl<N: Network> Owner<N, Plaintext<N>> { 58 /// Returns the owner as an `Entry`. 59 pub fn to_entry(&self) -> Entry<N, Plaintext<N>> { 60 match self { 61 Self::Public(owner) => Entry::Public(Plaintext::from(Literal::Address(*owner))), 62 Self::Private(plaintext) => Entry::Private(plaintext.clone()), 63 } 64 } 65 } 66 67 impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Eq for Owner<N, Private> {} 68 69 impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> PartialEq for Owner<N, Private> { 70 /// Returns `true` if `self` and `other` are equal. 71 fn eq(&self, other: &Self) -> bool { 72 *self.is_equal(other) 73 } 74 } 75 76 impl<N: Network, Private: Visibility<Boolean = Boolean<N>>> Equal<Self> for Owner<N, Private> { 77 type Output = Boolean<N>; 78 79 /// Returns `true` if `self` and `other` are equal. 80 fn is_equal(&self, other: &Self) -> Self::Output { 81 match (self, other) { 82 (Self::Public(a), Self::Public(b)) => a.is_equal(b), 83 (Self::Private(a), Self::Private(b)) => a.is_equal(b), 84 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::new(false), 85 } 86 } 87 88 /// Returns `true` if `self` and `other` are *not* equal. 89 fn is_not_equal(&self, other: &Self) -> Self::Output { 90 match (self, other) { 91 (Self::Public(a), Self::Public(b)) => a.is_not_equal(b), 92 (Self::Private(a), Self::Private(b)) => a.is_not_equal(b), 93 (Self::Public(_), _) | (Self::Private(_), _) => Boolean::new(true), 94 } 95 } 96 } 97 98 impl<N: Network> Owner<N, Plaintext<N>> { 99 /// Encrypts `self` under the given randomizer. 100 pub fn encrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Ciphertext<N>>> { 101 match self { 102 Self::Public(public) => { 103 // Ensure there is exactly zero randomizers. 104 ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len()); 105 // Return the owner. 106 Ok(Owner::Public(*public)) 107 } 108 Self::Private(Plaintext::Literal(Literal::Address(address), ..)) => { 109 // Ensure there is exactly one randomizer. 110 ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len()); 111 // Encrypt the owner. 112 let ciphertext = address.to_field()? + randomizer[0]; 113 // Return the encrypted owner. 114 Ok(Owner::Private(Ciphertext::from_fields(&[ciphertext])?)) 115 } 116 _ => bail!("Internal error: plaintext encryption corrupted in record owner"), 117 } 118 } 119 } 120 121 impl<N: Network> Owner<N, Ciphertext<N>> { 122 /// Decrypts the owner under the given randomizer. 123 pub fn decrypt_with_randomizer(&self, randomizer: &[Field<N>]) -> Result<Owner<N, Plaintext<N>>> { 124 match self { 125 Self::Public(public) => { 126 // Ensure there is exactly zero randomizers. 127 ensure!(randomizer.is_empty(), "Expected 0 randomizers, found {}", randomizer.len()); 128 // Return the owner. 129 Ok(Owner::Public(*public)) 130 } 131 Self::Private(ciphertext) => { 132 // Ensure there is exactly one randomizer. 133 ensure!(randomizer.len() == 1, "Expected 1 randomizer, found {}", randomizer.len()); 134 // Ensure there is exactly one field element in the ciphertext. 135 ensure!(ciphertext.len() == 1, "Expected 1 ciphertext, found {}", ciphertext.len()); 136 // Decrypt the owner. 137 let owner = Address::from_field(&(ciphertext[0] - randomizer[0]))?; 138 // Return the owner. 139 Ok(Owner::Private(Plaintext::from(Literal::Address(owner)))) 140 } 141 } 142 } 143 } 144 145 impl<N: Network> Debug for Owner<N, Plaintext<N>> { 146 /// Prints the owner as a string. 147 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 148 Display::fmt(self, f) 149 } 150 } 151 152 impl<N: Network> Display for Owner<N, Plaintext<N>> { 153 /// Prints the owner as a string, i.e. `ax1xxx.public`. 154 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 155 match self { 156 Self::Public(owner) => write!(f, "{owner}.public"), 157 Self::Private(Plaintext::Literal(Literal::Address(owner), ..)) => write!(f, "{owner}.private"), 158 _ => N::halt("Internal error: plaintext fmt corrupted in record owner"), 159 } 160 } 161 }