use crate as solana_libra_crypto;
use crate::{
bls12381::{BLS12381PrivateKey, BLS12381PublicKey, BLS12381Signature},
ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature},
traits::*,
unit_tests::uniform_keypair_strategy,
};
use crate::hash::HashValue;
use proptest::prelude::*;
use serde::{Deserialize, Serialize};
use solana_libra_crypto_derive::{
PrivateKey, PublicKey, Signature, SigningKey, SilentDebug, ValidKey, VerifyingKey,
};
#[derive(
Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, ValidKey, PublicKey, VerifyingKey,
)]
#[PrivateKeyType = "PrivateK"]
#[SignatureType = "Sig"]
enum PublicK {
Ed(Ed25519PublicKey),
BLS(BLS12381PublicKey),
}
#[derive(Serialize, Deserialize, SilentDebug, ValidKey, PrivateKey, SigningKey)]
#[PublicKeyType = "PublicK"]
#[SignatureType = "Sig"]
enum PrivateK {
Ed(Ed25519PrivateKey),
BLS(BLS12381PrivateKey),
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Signature)]
#[PublicKeyType = "PublicK"]
#[PrivateKeyType = "PrivateK"]
enum Sig {
Ed(Ed25519Signature),
BLS(BLS12381Signature),
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(20))]
#[test]
fn test_keys_mix(
hash in any::<HashValue>(),
ed_keypair1 in uniform_keypair_strategy::<Ed25519PrivateKey, Ed25519PublicKey>(),
ed_keypair2 in uniform_keypair_strategy::<Ed25519PrivateKey, Ed25519PublicKey>(),
bls_keypair in uniform_keypair_strategy::<BLS12381PrivateKey, BLS12381PublicKey>()
) {
let mut l: Vec<Ed25519PrivateKey> = vec![];
l.push(ed_keypair1.private_key);
let ed_key = l.pop().unwrap();
let signature = ed_key.sign_message(&hash);
prop_assert!(signature.verify(&hash, &ed_keypair1.public_key).is_ok());
let mut l2: Vec<PrivateK> = vec![];
l2.push(PrivateK::BLS(bls_keypair.private_key));
l2.push(PrivateK::Ed(ed_keypair2.private_key));
let ed_key = l2.pop().unwrap();
let ed_signature = ed_key.sign_message(&hash);
let ed_pubkey2 = PublicK::Ed(ed_keypair2.public_key);
let good_sigver = ed_signature.verify(&hash, &ed_pubkey2);
prop_assert!(good_sigver.is_ok(), "{:?}", good_sigver);
let bls_pubkey = PublicK::BLS(bls_keypair.public_key);
let bad_sigver = ed_signature.verify(&hash, &bls_pubkey);
prop_assert!(bad_sigver.is_err(), "{:?}", bad_sigver);
let bls_key = l2.pop().unwrap();
let bls_signature = bls_key.sign_message(&hash);
let good_sigver = bls_signature.verify(&hash, &bls_pubkey);
prop_assert!(good_sigver.is_ok(), "{:?}", good_sigver);
let bad_sigver = bls_signature.verify(&hash, &ed_pubkey2);
prop_assert!(bad_sigver.is_err(), "{:?}", bad_sigver);
}
}