snarkvm_console_account/
lib.rs1#![forbid(unsafe_code)]
17#![allow(clippy::too_many_arguments)]
18#![warn(clippy::cast_possible_truncation)]
19#![cfg_attr(test, allow(clippy::assertions_on_result_states))]
20
21pub use snarkvm_console_types::{Address, Field, Group, Scalar, environment::prelude::*};
22
23mod address;
24
25#[cfg(feature = "compute_key")]
26pub mod compute_key;
27#[cfg(feature = "compute_key")]
28pub use compute_key::*;
29
30#[cfg(feature = "graph_key")]
31pub mod graph_key;
32#[cfg(feature = "graph_key")]
33pub use graph_key::*;
34
35#[cfg(feature = "private_key")]
36pub mod private_key;
37#[cfg(feature = "private_key")]
38pub use private_key::*;
39
40#[cfg(feature = "signature")]
41pub mod signature;
42#[cfg(feature = "signature")]
43pub use signature::*;
44
45#[cfg(feature = "view_key")]
46pub mod view_key;
47#[cfg(feature = "view_key")]
48pub use view_key::*;
49
50#[cfg(test)]
51mod tests {
52 use crate::{Address, ComputeKey, PrivateKey, Signature, ViewKey};
53 use snarkvm_console_network::{MainnetV0, prelude::*};
54
55 type CurrentNetwork = MainnetV0;
56
57 const ALEO_PRIVATE_KEY: &str = "APrivateKey1zkp8cC4jgHEBnbtu3xxs1Ndja2EMizcvTRDq5Nikdkukg1p";
58 const ALEO_VIEW_KEY: &str = "AViewKey1n1n3ZbnVEtXVe3La2xWkUvY3EY7XaCG6RZJJ3tbvrrrD";
59 const ALEO_ADDRESS: &str = "aleo1wvgwnqvy46qq0zemj0k6sfp3zv0mp77rw97khvwuhac05yuwscxqmfyhwf";
60
61 const ITERATIONS: usize = 1_000;
62
63 #[test]
64 fn test_account_derivation() {
65 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
66 let view_key = ViewKey::<CurrentNetwork>::try_from(&private_key).unwrap();
67 let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
68
69 assert_eq!(ALEO_PRIVATE_KEY, private_key.to_string());
70 assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
71 assert_eq!(ALEO_ADDRESS, address.to_string());
72 }
73
74 #[test]
75 fn test_private_key_from_str() {
76 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
77 assert_eq!(ALEO_PRIVATE_KEY, private_key.to_string());
78 }
79
80 #[test]
81 fn test_private_key_from_invalid_str() {
82 assert!(PrivateKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).is_err());
83 assert!(PrivateKey::<CurrentNetwork>::from_str(ALEO_ADDRESS).is_err());
84 assert!(PrivateKey::<CurrentNetwork>::from_str("APrivateKey1abcdefghijklmnopqrstuvwxyz").is_err());
85 assert!(PrivateKey::<CurrentNetwork>::from_str("APrivateKey1").is_err());
86 assert!(PrivateKey::<CurrentNetwork>::from_str("").is_err());
87 }
88
89 #[test]
90 fn test_private_key_try_into_view_key() {
91 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
92 let view_key: ViewKey<_> = private_key.try_into().unwrap();
93 assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
94 }
95
96 #[test]
97 fn test_view_key_from_str() {
98 let view_key = ViewKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).unwrap();
99 assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
100 }
101
102 #[test]
103 fn test_view_key_from_invalid_str() {
104 assert!(ViewKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).is_err());
105 assert!(ViewKey::<CurrentNetwork>::from_str(ALEO_ADDRESS).is_err());
106 assert!(ViewKey::<CurrentNetwork>::from_str("AViewKey1abcdefghijklmnopqrstuvwxyz").is_err());
107 assert!(ViewKey::<CurrentNetwork>::from_str("AViewKey1").is_err());
108 assert!(ViewKey::<CurrentNetwork>::from_str("").is_err());
109 }
110
111 #[test]
112 fn test_private_key_try_into_address() {
113 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
114 let address: Address<_> = private_key.try_into().unwrap();
115 assert_eq!(ALEO_ADDRESS, address.to_string());
116 }
117
118 #[test]
119 fn test_compute_key_try_into_address() {
120 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
121 let compute_key: ComputeKey<_> = private_key.try_into().unwrap();
122 let address: Address<_> = compute_key.try_into().unwrap();
123 assert_eq!(ALEO_ADDRESS, address.to_string());
124 }
125
126 #[test]
127 fn test_view_key_try_into_address() {
128 let view_key = ViewKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).unwrap();
129 let address: Address<_> = view_key.try_into().unwrap();
130 assert_eq!(ALEO_ADDRESS, address.to_string());
131 }
132
133 #[test]
134 fn test_address_from_str() {
135 let address = Address::<CurrentNetwork>::from_str(ALEO_ADDRESS).unwrap();
136 assert_eq!(ALEO_ADDRESS, address.to_string());
137 }
138
139 #[test]
140 fn test_address_from_invalid_str() {
141 assert!(Address::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).is_err());
142 assert!(Address::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).is_err());
143 assert!(Address::<CurrentNetwork>::from_str("aleo1abcdefghijklmnopqrstuvwxyz").is_err());
144 assert!(Address::<CurrentNetwork>::from_str("aleo1").is_err());
145 assert!(Address::<CurrentNetwork>::from_str("").is_err());
146 }
147
148 #[test]
149 fn test_sign_bits() {
150 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
151 let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
152
153 let mut rng = TestRng::default();
154
155 for i in 0..ITERATIONS {
156 let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
157 let signature = private_key.sign_bits(&message, &mut rng).unwrap();
158 let verification = signature.verify_bits(&address, &message);
159 assert!(verification);
160 }
161 }
162
163 #[test]
164 fn test_invalid_sign_bits() {
165 let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
166 let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
167
168 let mut rng = TestRng::default();
169
170 for i in 0..ITERATIONS {
171 let message = "Hi, I'm an Aleo account signature!".as_bytes().to_bits_le();
172 let incorrect_message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
173
174 let signature = private_key.sign_bits(&message, &mut rng).unwrap();
175 let verification = signature.verify_bits(&address, &incorrect_message);
176 assert!(!verification);
177 }
178 }
179
180 #[test]
181 fn test_aleo_signature_bech32() {
182 let mut rng = TestRng::default();
183
184 for i in 0..25 {
185 let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
187
188 let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
190 let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
191
192 let candidate_string = &expected_signature.to_string();
193 assert_eq!(216, candidate_string.len(), "Update me if serialization has changed");
194 assert_eq!("sign1", &candidate_string[0..5], "Update me if the prefix has changed");
195 }
196 }
197
198 #[test]
199 fn test_aleo_signature_serde_json() {
200 let mut rng = TestRng::default();
201
202 for i in 0..25 {
203 let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
205
206 let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
208 let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
209
210 let expected_string = &expected_signature.to_string();
212 let candidate_string = serde_json::to_string(&expected_signature).unwrap();
213 assert_eq!(expected_string, serde_json::Value::from_str(&candidate_string).unwrap().as_str().unwrap());
214
215 assert_eq!(expected_signature, serde_json::from_str(&candidate_string).unwrap());
217 assert_eq!(expected_signature, Signature::<CurrentNetwork>::from_str(expected_string).unwrap());
218 }
219 }
220
221 #[test]
222 fn test_aleo_signature_bincode() {
223 let mut rng = TestRng::default();
224
225 for i in 0..25 {
226 let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
228
229 let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
231 let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
232
233 let expected_bytes = expected_signature.to_bytes_le().unwrap();
235 let candidate_bytes = bincode::serialize(&expected_signature).unwrap();
236 assert_eq!(128, expected_bytes.len(), "Update me if serialization has changed");
237 assert_eq!(&expected_bytes[..], &candidate_bytes[8..]);
238
239 assert_eq!(expected_signature, bincode::deserialize(&candidate_bytes[..]).unwrap());
241 assert_eq!(expected_signature, Signature::<CurrentNetwork>::read_le(&expected_bytes[..]).unwrap());
242 }
243 }
244}