use rand::{rngs::StdRng, SeedableRng};
use std::convert::TryFrom;
use crate::{
ed25519::{
Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature, ED25519_PRIVATE_KEY_LENGTH,
ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH,
},
multi_ed25519::{MultiEd25519PrivateKey, MultiEd25519PublicKey, MultiEd25519Signature},
test_utils::{TestDiemCrypto, TEST_SEED},
Signature, SigningKey, Uniform,
};
#[test]
fn ed25519_bcs_material() {
use std::borrow::Cow;
let private_key =
Ed25519PrivateKey::try_from([1u8; ED25519_PRIVATE_KEY_LENGTH].as_ref()).unwrap();
let public_key = Ed25519PublicKey::from(&private_key);
let serialized_public_key = bcs::to_bytes(&Cow::Borrowed(&public_key)).unwrap();
assert_eq!(serialized_public_key.len(), 1 + ED25519_PUBLIC_KEY_LENGTH);
let deserialized_public_key: Ed25519PublicKey =
bcs::from_bytes(&serialized_public_key).unwrap();
assert_eq!(deserialized_public_key, public_key);
let message = TestDiemCrypto("Hello, World".to_string());
let signature: Ed25519Signature = private_key.sign(&message);
let serialized_signature = bcs::to_bytes(&Cow::Borrowed(&signature)).unwrap();
assert_eq!(serialized_signature.len(), 1 + ED25519_SIGNATURE_LENGTH);
let deserialized_signature: Ed25519Signature = bcs::from_bytes(&serialized_signature).unwrap();
assert_eq!(deserialized_signature, signature);
let verified_signature = signature.verify(&message, &public_key);
assert!(verified_signature.is_ok())
}
#[test]
fn multi_ed25519_bcs_material() {
use std::borrow::Cow;
fn generate_keys(n: usize) -> Vec<Ed25519PrivateKey> {
let mut rng = StdRng::from_seed(TEST_SEED);
(0..n)
.map(|_| Ed25519PrivateKey::generate(&mut rng))
.collect()
}
let num_of_keys = 10;
let threshold = 7;
let private_keys_10 = generate_keys(num_of_keys);
let multi_private_key_7of10 = MultiEd25519PrivateKey::new(private_keys_10, threshold).unwrap();
let multi_public_key_7of10 = MultiEd25519PublicKey::from(&multi_private_key_7of10);
let serialized_multi_public_key =
bcs::to_bytes(&Cow::Borrowed(&multi_public_key_7of10)).unwrap();
assert_eq!(
serialized_multi_public_key.len(),
2 + num_of_keys * ED25519_PUBLIC_KEY_LENGTH + 1
);
let deserialized_multi_public_key: MultiEd25519PublicKey =
bcs::from_bytes(&serialized_multi_public_key).unwrap();
assert_eq!(deserialized_multi_public_key, multi_public_key_7of10);
let message = TestDiemCrypto("Hello, World".to_string());
let multi_signature_7of10: MultiEd25519Signature = multi_private_key_7of10.sign(&message);
let serialized_multi_signature = bcs::to_bytes(&Cow::Borrowed(&multi_signature_7of10)).unwrap();
assert_eq!(
serialized_multi_signature.len(),
2 + threshold as usize * ED25519_SIGNATURE_LENGTH + 4
);
assert_eq!(
multi_signature_7of10.bitmap(),
&[0b1111_1110, 0u8, 0u8, 0u8]
);
assert!(multi_signature_7of10
.verify(&message, &multi_public_key_7of10)
.is_ok());
}