/ console / program / src / data / record / helpers / owner.rs
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  }