snarkvm_console_account/
lib.rs#![forbid(unsafe_code)]
#![allow(clippy::too_many_arguments)]
#![warn(clippy::cast_possible_truncation)]
#![cfg_attr(test, allow(clippy::assertions_on_result_states))]
pub use snarkvm_console_types::{Address, Field, Group, Scalar, environment::prelude::*};
mod address;
#[cfg(feature = "compute_key")]
pub mod compute_key;
#[cfg(feature = "compute_key")]
pub use compute_key::*;
#[cfg(feature = "graph_key")]
pub mod graph_key;
#[cfg(feature = "graph_key")]
pub use graph_key::*;
#[cfg(feature = "private_key")]
pub mod private_key;
#[cfg(feature = "private_key")]
pub use private_key::*;
#[cfg(feature = "signature")]
pub mod signature;
#[cfg(feature = "signature")]
pub use signature::*;
#[cfg(feature = "view_key")]
pub mod view_key;
#[cfg(feature = "view_key")]
pub use view_key::*;
#[cfg(test)]
mod tests {
use crate::{Address, ComputeKey, PrivateKey, Signature, ViewKey};
use snarkvm_console_network::{MainnetV0, prelude::*};
type CurrentNetwork = MainnetV0;
const ALEO_PRIVATE_KEY: &str = "APrivateKey1zkp8cC4jgHEBnbtu3xxs1Ndja2EMizcvTRDq5Nikdkukg1p";
const ALEO_VIEW_KEY: &str = "AViewKey1n1n3ZbnVEtXVe3La2xWkUvY3EY7XaCG6RZJJ3tbvrrrD";
const ALEO_ADDRESS: &str = "aleo1wvgwnqvy46qq0zemj0k6sfp3zv0mp77rw97khvwuhac05yuwscxqmfyhwf";
const ITERATIONS: usize = 1_000;
#[test]
fn test_account_derivation() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let view_key = ViewKey::<CurrentNetwork>::try_from(&private_key).unwrap();
let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
assert_eq!(ALEO_PRIVATE_KEY, private_key.to_string());
assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
assert_eq!(ALEO_ADDRESS, address.to_string());
}
#[test]
fn test_private_key_from_str() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
assert_eq!(ALEO_PRIVATE_KEY, private_key.to_string());
}
#[test]
fn test_private_key_from_invalid_str() {
assert!(PrivateKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).is_err());
assert!(PrivateKey::<CurrentNetwork>::from_str(ALEO_ADDRESS).is_err());
assert!(PrivateKey::<CurrentNetwork>::from_str("APrivateKey1abcdefghijklmnopqrstuvwxyz").is_err());
assert!(PrivateKey::<CurrentNetwork>::from_str("APrivateKey1").is_err());
assert!(PrivateKey::<CurrentNetwork>::from_str("").is_err());
}
#[test]
fn test_private_key_try_into_view_key() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let view_key: ViewKey<_> = private_key.try_into().unwrap();
assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
}
#[test]
fn test_view_key_from_str() {
let view_key = ViewKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).unwrap();
assert_eq!(ALEO_VIEW_KEY, view_key.to_string());
}
#[test]
fn test_view_key_from_invalid_str() {
assert!(ViewKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).is_err());
assert!(ViewKey::<CurrentNetwork>::from_str(ALEO_ADDRESS).is_err());
assert!(ViewKey::<CurrentNetwork>::from_str("AViewKey1abcdefghijklmnopqrstuvwxyz").is_err());
assert!(ViewKey::<CurrentNetwork>::from_str("AViewKey1").is_err());
assert!(ViewKey::<CurrentNetwork>::from_str("").is_err());
}
#[test]
fn test_private_key_try_into_address() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let address: Address<_> = private_key.try_into().unwrap();
assert_eq!(ALEO_ADDRESS, address.to_string());
}
#[test]
fn test_compute_key_try_into_address() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let compute_key: ComputeKey<_> = private_key.try_into().unwrap();
let address: Address<_> = compute_key.try_into().unwrap();
assert_eq!(ALEO_ADDRESS, address.to_string());
}
#[test]
fn test_view_key_try_into_address() {
let view_key = ViewKey::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).unwrap();
let address: Address<_> = view_key.try_into().unwrap();
assert_eq!(ALEO_ADDRESS, address.to_string());
}
#[test]
fn test_address_from_str() {
let address = Address::<CurrentNetwork>::from_str(ALEO_ADDRESS).unwrap();
assert_eq!(ALEO_ADDRESS, address.to_string());
}
#[test]
fn test_address_from_invalid_str() {
assert!(Address::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).is_err());
assert!(Address::<CurrentNetwork>::from_str(ALEO_VIEW_KEY).is_err());
assert!(Address::<CurrentNetwork>::from_str("aleo1abcdefghijklmnopqrstuvwxyz").is_err());
assert!(Address::<CurrentNetwork>::from_str("aleo1").is_err());
assert!(Address::<CurrentNetwork>::from_str("").is_err());
}
#[test]
fn test_sign_bits() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
let mut rng = TestRng::default();
for i in 0..ITERATIONS {
let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
let signature = private_key.sign_bits(&message, &mut rng).unwrap();
let verification = signature.verify_bits(&address, &message);
assert!(verification);
}
}
#[test]
fn test_invalid_sign_bits() {
let private_key = PrivateKey::<CurrentNetwork>::from_str(ALEO_PRIVATE_KEY).unwrap();
let address = Address::<CurrentNetwork>::try_from(&private_key).unwrap();
let mut rng = TestRng::default();
for i in 0..ITERATIONS {
let message = "Hi, I'm an Aleo account signature!".as_bytes().to_bits_le();
let incorrect_message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
let signature = private_key.sign_bits(&message, &mut rng).unwrap();
let verification = signature.verify_bits(&address, &incorrect_message);
assert!(!verification);
}
}
#[test]
fn test_aleo_signature_bech32() {
let mut rng = TestRng::default();
for i in 0..25 {
let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
let candidate_string = &expected_signature.to_string();
assert_eq!(216, candidate_string.len(), "Update me if serialization has changed");
assert_eq!("sign1", &candidate_string[0..5], "Update me if the prefix has changed");
}
}
#[test]
fn test_aleo_signature_serde_json() {
let mut rng = TestRng::default();
for i in 0..25 {
let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
let expected_string = &expected_signature.to_string();
let candidate_string = serde_json::to_string(&expected_signature).unwrap();
assert_eq!(expected_string, serde_json::Value::from_str(&candidate_string).unwrap().as_str().unwrap());
assert_eq!(expected_signature, serde_json::from_str(&candidate_string).unwrap());
assert_eq!(expected_signature, Signature::<CurrentNetwork>::from_str(expected_string).unwrap());
}
}
#[test]
fn test_aleo_signature_bincode() {
let mut rng = TestRng::default();
for i in 0..25 {
let private_key = PrivateKey::<CurrentNetwork>::new(&mut rng).unwrap();
let message: Vec<bool> = (0..(32 * i)).map(|_| bool::rand(&mut rng)).collect();
let expected_signature = private_key.sign_bits(&message, &mut rng).unwrap();
let expected_bytes = expected_signature.to_bytes_le().unwrap();
let candidate_bytes = bincode::serialize(&expected_signature).unwrap();
assert_eq!(128, expected_bytes.len(), "Update me if serialization has changed");
assert_eq!(&expected_bytes[..], &candidate_bytes[8..]);
assert_eq!(expected_signature, bincode::deserialize(&candidate_bytes[..]).unwrap());
assert_eq!(expected_signature, Signature::<CurrentNetwork>::read_le(&expected_bytes[..]).unwrap());
}
}
}