/ circuit / account / src / view_key / to_address.rs
to_address.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 super::*;
17  
18  impl<A: Alpha> ViewKey<A> {
19      /// Returns the account address for this account view key.
20      pub fn to_address(&self) -> Address<A> {
21          self.1.get_or_init(|| Address::from_group(A::g_scalar_multiply(&self.0))).clone()
22      }
23  }
24  
25  #[cfg(test)]
26  mod tests {
27      use super::*;
28      use crate::{Circuit, helpers::generate_account};
29  
30      use anyhow::Result;
31  
32      const ITERATIONS: u64 = 100;
33  
34      fn check_to_address(
35          mode: Mode,
36          num_constants: u64,
37          num_public: u64,
38          num_private: u64,
39          num_constraints: u64,
40      ) -> Result<()> {
41          for i in 0..ITERATIONS {
42              // Generate a private key, compute key, view key, and address.
43              let (_private_key, _compute_key, view_key, address) = generate_account()?;
44  
45              // Initialize the view key.
46              let candidate = ViewKey::<Circuit>::new(mode, view_key);
47  
48              Circuit::scope(format!("{mode} {i}"), || {
49                  let candidate = candidate.to_address();
50                  assert_eq!(*address, candidate.to_group().eject_value());
51                  // TODO (howardwu): Resolve skipping the cost count checks for the burn-in round.
52                  if i > 0 {
53                      assert_scope!(<=num_constants, num_public, num_private, num_constraints);
54                  }
55              });
56              Circuit::reset();
57          }
58          Ok(())
59      }
60  
61      #[test]
62      fn test_to_address_constant() -> Result<()> {
63          check_to_address(Mode::Constant, 1251, 0, 0, 0)
64      }
65  
66      #[test]
67      fn test_to_address_public() -> Result<()> {
68          check_to_address(Mode::Public, 500, 0, 1751, 1753)
69      }
70  
71      #[test]
72      fn test_to_address_private() -> Result<()> {
73          check_to_address(Mode::Private, 500, 0, 1751, 1753)
74      }
75  }