Skip to main content

snarkvm_circuit_account/private_key/
mod.rs

1// Copyright (c) 2019-2026 Provable Inc.
2// This file is part of the snarkVM 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
16mod to_compute_key;
17mod to_view_key;
18
19#[cfg(test)]
20use snarkvm_circuit_types::environment::assert_scope;
21
22use crate::{ComputeKey, ViewKey};
23use snarkvm_circuit_network::Aleo;
24use snarkvm_circuit_types::{Scalar, environment::prelude::*};
25
26pub struct PrivateKey<A: Aleo> {
27    /// The signature secret key.
28    sk_sig: Scalar<A>,
29    /// The signature secret randomizer.
30    r_sig: Scalar<A>,
31}
32
33impl<A: Aleo> Inject for PrivateKey<A> {
34    type Primitive = console::PrivateKey<A::Network>;
35
36    /// Initializes an account private key from the given mode and native private key.
37    fn new(mode: Mode, private_key: Self::Primitive) -> Self {
38        Self { sk_sig: Scalar::new(mode, private_key.sk_sig()), r_sig: Scalar::new(mode, private_key.r_sig()) }
39    }
40}
41
42impl<A: Aleo> PrivateKey<A> {
43    /// Returns the signature secret key.
44    pub const fn sk_sig(&self) -> &Scalar<A> {
45        &self.sk_sig
46    }
47
48    /// Returns the signature randomizer.
49    pub const fn r_sig(&self) -> &Scalar<A> {
50        &self.r_sig
51    }
52}
53
54impl<A: Aleo> Eject for PrivateKey<A> {
55    type Primitive = (console::Scalar<A::Network>, console::Scalar<A::Network>);
56
57    /// Ejects the mode of the account private key.
58    fn eject_mode(&self) -> Mode {
59        (&self.sk_sig, &self.r_sig).eject_mode()
60    }
61
62    /// Ejects the account private key as `(sk_sig, r_sig)`.
63    fn eject_value(&self) -> Self::Primitive {
64        (&self.sk_sig, &self.r_sig).eject_value()
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::{Circuit, helpers::generate_account};
72
73    use anyhow::Result;
74
75    const ITERATIONS: u64 = 10;
76
77    fn check_new(
78        mode: Mode,
79        num_constants: u64,
80        num_public: u64,
81        num_private: u64,
82        num_constraints: u64,
83    ) -> Result<()> {
84        for _ in 0..ITERATIONS {
85            // Generate a private key, compute key, view key, and address.
86            let (private_key, _compute_key, _view_key, _address) = generate_account()?;
87
88            // Retrieve the native private key components.
89            let sk_sig = private_key.sk_sig();
90            let r_sig = private_key.r_sig();
91
92            Circuit::scope(format!("New {mode}"), || {
93                let candidate = PrivateKey::<Circuit>::new(mode, private_key);
94                assert_eq!(mode, candidate.eject_mode());
95                assert_eq!((sk_sig, r_sig), candidate.eject_value());
96                assert_scope!(num_constants, num_public, num_private, num_constraints);
97            });
98            Circuit::reset();
99        }
100        Ok(())
101    }
102
103    #[test]
104    fn test_private_key_new_constant() -> Result<()> {
105        check_new(Mode::Constant, 2, 0, 0, 0)
106    }
107
108    #[test]
109    fn test_private_key_new_public() -> Result<()> {
110        check_new(Mode::Public, 0, 2, 0, 0)
111    }
112
113    #[test]
114    fn test_private_key_new_private() -> Result<()> {
115        check_new(Mode::Private, 0, 0, 2, 0)
116    }
117}