mod equal;
mod from;
mod from_private_key;
mod helpers;
mod ternary;
mod to_address;
#[cfg(test)]
use snarkvm_circuit_types::environment::{assert_count, assert_output_mode, assert_scope};
use crate::PrivateKey;
use snarkvm_circuit_network::Aleo;
use snarkvm_circuit_types::{environment::prelude::*, Address, Boolean, Field, Group, Scalar};
#[derive(Clone)]
pub struct ComputeKey<A: Aleo> {
pk_sig: Group<A>,
pr_sig: Group<A>,
sk_prf: Scalar<A>,
}
#[cfg(console)]
impl<A: Aleo> Inject for ComputeKey<A> {
type Primitive = console::ComputeKey<A::Network>;
fn new(mode: Mode, compute_key: Self::Primitive) -> Self {
let pk_sig = Group::new(mode, compute_key.pk_sig());
let pr_sig = Group::new(mode, compute_key.pr_sig());
Self::from((pk_sig, pr_sig))
}
}
impl<A: Aleo> ComputeKey<A> {
pub const fn pk_sig(&self) -> &Group<A> {
&self.pk_sig
}
pub const fn pr_sig(&self) -> &Group<A> {
&self.pr_sig
}
pub const fn sk_prf(&self) -> &Scalar<A> {
&self.sk_prf
}
}
#[cfg(console)]
impl<A: Aleo> Eject for ComputeKey<A> {
type Primitive = console::ComputeKey<A::Network>;
fn eject_mode(&self) -> Mode {
(&self.pk_sig, &self.pr_sig, &self.sk_prf).eject_mode()
}
fn eject_value(&self) -> Self::Primitive {
match Self::Primitive::try_from((&self.pk_sig, &self.pr_sig).eject_value()) {
Ok(compute_key) => compute_key,
Err(error) => A::halt(format!("Failed to eject the compute key: {error}")),
}
}
}
#[cfg(all(test, console))]
pub(crate) mod tests {
use super::*;
use crate::{helpers::generate_account, Circuit};
use anyhow::Result;
const ITERATIONS: u64 = 250;
fn check_new(
mode: Mode,
num_constants: u64,
num_public: u64,
num_private: u64,
num_constraints: u64,
) -> Result<()> {
for i in 0..ITERATIONS {
let (_private_key, compute_key, _view_key, _address) = generate_account()?;
Circuit::scope(format!("New {mode}"), || {
let candidate = ComputeKey::<Circuit>::new(mode, compute_key);
match mode.is_constant() {
true => assert_eq!(Mode::Constant, candidate.eject_mode()),
false => assert_eq!(Mode::Private, candidate.eject_mode()),
};
assert_eq!(compute_key, candidate.eject_value());
if i > 0 {
assert_scope!(num_constants, num_public, num_private, num_constraints);
}
});
Circuit::reset();
}
Ok(())
}
#[test]
fn test_compute_key_new_constant() -> Result<()> {
check_new(Mode::Constant, 274, 0, 0, 0)
}
#[test]
fn test_compute_key_new_public() -> Result<()> {
check_new(Mode::Public, 9, 4, 869, 873)
}
#[test]
fn test_compute_key_new_private() -> Result<()> {
check_new(Mode::Private, 9, 0, 873, 873)
}
}