use crate::{
bls12381,
bls12381::{
bls12381_keys::{PrivateKey, PublicKey},
ProofOfPossession,
},
test_utils::{random_subset, KeyPair, TestAptosCrypto},
Signature, SigningKey, Uniform,
};
use rand::{distributions::Alphanumeric, Rng};
use rand_core::OsRng;
use std::convert::TryFrom;
use std::iter::zip;
#[test]
fn bls12381_sigshare_verify() {
let mut rng = OsRng;
let message = b"Hello world";
let message_wrong = b"Wello Horld";
let key_pair = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let key_pair_wrong = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let signature = key_pair.private_key.sign_arbitrary_message(message);
let signature_wrong = key_pair_wrong.private_key.sign_arbitrary_message(message);
assert!(signature
.verify_arbitrary_msg(message, &key_pair.public_key)
.is_ok());
assert!(signature_wrong
.verify_arbitrary_msg(message, &key_pair_wrong.public_key)
.is_ok());
assert!(signature
.verify_arbitrary_msg(message, &key_pair_wrong.public_key)
.is_err());
assert!(signature
.verify_arbitrary_msg(message_wrong, &key_pair.public_key)
.is_err());
assert!(signature_wrong
.verify_arbitrary_msg(message, &key_pair.public_key)
.is_err());
}
#[test]
fn bls12381_pop_verify() {
let mut rng = OsRng;
let keypair1 = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let keypair2 = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let pop1 = ProofOfPossession::create_with_pubkey(&keypair1.private_key, &keypair1.public_key);
let pop2 = ProofOfPossession::create(&keypair2.private_key);
let pop_bad =
ProofOfPossession::create_with_pubkey(&keypair1.private_key, &keypair2.public_key);
assert!(pop1.verify(&keypair1.public_key).is_ok());
assert!(pop2.verify(&keypair2.public_key).is_ok());
assert!(pop1.verify(&keypair2.public_key).is_err());
assert!(pop2.verify(&keypair1.public_key).is_err());
assert!(pop_bad.verify(&keypair2.public_key).is_err());
}
fn bls12381_keygen(num_signers: usize, mut rng: &mut OsRng) -> Vec<KeyPair<PrivateKey, PublicKey>> {
let mut key_pairs = vec![];
for _ in 0..num_signers {
key_pairs.push(KeyPair::<PrivateKey, PublicKey>::generate(&mut rng));
}
key_pairs
}
fn random_message_for_signing(rng: &mut OsRng) -> TestAptosCrypto {
TestAptosCrypto(
rng.sample_iter(&Alphanumeric)
.take(256)
.map(char::from)
.collect::<String>(),
)
}
fn random_messages_for_signing(rng: &mut OsRng, n: usize) -> Vec<TestAptosCrypto> {
(0..n)
.map(|_| random_message_for_signing(rng))
.collect::<Vec<TestAptosCrypto>>()
}
#[test]
fn bls12381_multisig_should_verify() {
let mut rng = OsRng;
let message = random_message_for_signing(&mut rng);
let message_wrong = random_message_for_signing(&mut rng);
let num_signers = 1000;
let key_pairs = bls12381_keygen(num_signers, &mut rng);
let mut signatures = vec![];
let mut pubkeys: Vec<&PublicKey> = vec![];
let good_step = 2;
for keys in key_pairs.iter().step_by(good_step) {
let signature = keys.private_key.sign(&message);
signatures.push(signature);
pubkeys.push(&keys.public_key);
}
let multisig = bls12381::Signature::aggregate(signatures).unwrap();
let aggpk = PublicKey::aggregate(pubkeys).unwrap();
assert!(multisig.verify(&message, &aggpk).is_ok());
assert!(multisig.verify(&message_wrong, &aggpk).is_err());
}
#[test]
fn bls12381_serialize_sig() {
let mut rng = OsRng;
let message = b"Hello world";
let key_pair = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let signature = key_pair.private_key.sign_arbitrary_message(message);
let sig_bytes = signature.to_bytes();
let signature_deserialized = bls12381::Signature::try_from(&sig_bytes[..]).unwrap();
assert_eq!(signature, signature_deserialized);
}
#[test]
fn bls12381_aggsig_should_verify() {
let mut rng = OsRng;
let num_signers = 1000;
let messages = random_messages_for_signing(&mut rng, num_signers);
let messages_wrong = random_messages_for_signing(&mut rng, num_signers);
let key_pairs = bls12381_keygen(num_signers, &mut rng);
let mut signatures = vec![];
let mut pubkeys: Vec<&PublicKey> = vec![];
for i in 0..num_signers {
let msg = &messages[i];
let key = &key_pairs[i];
signatures.push(key.private_key.sign(msg));
pubkeys.push(&key.public_key);
}
let aggsig = bls12381::Signature::aggregate(signatures).unwrap();
let msgs_refs = messages.iter().collect::<Vec<&TestAptosCrypto>>();
assert!(aggsig.verify_aggregate(&msgs_refs, &pubkeys).is_ok());
let msgs_wrong_refs = messages_wrong.iter().collect::<Vec<&TestAptosCrypto>>();
assert!(aggsig.verify_aggregate(&msgs_wrong_refs, &pubkeys).is_err());
}
#[test]
fn bls12381_multisig_wrong_messages_aggregated() {
let mut rng = OsRng;
let message = random_message_for_signing(&mut rng);
let message_wrong = random_message_for_signing(&mut rng);
let num_signers = 500;
let key_pairs = bls12381_keygen(num_signers, &mut rng);
assert_eq!(key_pairs.len(), num_signers);
let mut signatures = vec![];
let mut pubkeys: Vec<&PublicKey> = vec![];
for (i, key_pair) in key_pairs.iter().enumerate() {
let signature = if i % 2 == 0 {
key_pair.private_key.sign(&message)
} else {
key_pair.private_key.sign(&message_wrong)
};
signatures.push(signature);
pubkeys.push(&key_pair.public_key);
}
let multisig = bls12381::Signature::aggregate(signatures).unwrap();
let aggpk = PublicKey::aggregate(pubkeys).unwrap();
assert!(multisig.verify(&message, &aggpk).is_err());
assert!(multisig.verify(&message_wrong, &aggpk).is_err());
}
pub fn random_different_signer_sets(
rng: &mut OsRng,
num_signers: usize,
subset_size: usize,
) -> (Vec<usize>, Vec<usize>) {
let signers1 = random_subset(rng, num_signers, subset_size);
let mut signers2 = random_subset(rng, num_signers, subset_size);
while signers1 == signers2 {
signers2 = random_subset(rng, num_signers, subset_size);
}
(signers1, signers2)
}
#[test]
fn bls12381_multisig_wrong_pks_aggregated() {
let mut rng = OsRng;
let message1 = random_message_for_signing(&mut rng);
let message2 = random_message_for_signing(&mut rng);
let num_signers = 1000;
let key_pairs = bls12381_keygen(num_signers, &mut rng);
assert_eq!(key_pairs.len(), num_signers);
let (signers1, signers2) = random_different_signer_sets(&mut rng, num_signers, num_signers / 2);
let mut signatures1 = vec![];
let mut signatures2 = vec![];
let mut pubkeys1 = vec![];
let mut pubkeys2 = vec![];
for (i1, i2) in zip(signers1, signers2) {
signatures1.push(key_pairs[i1].private_key.sign(&message1));
signatures2.push(key_pairs[i2].private_key.sign(&message2));
pubkeys1.push(&key_pairs[i1].public_key);
pubkeys2.push(&key_pairs[i2].public_key);
}
assert_ne!(signatures1.len(), 0);
assert_ne!(signatures2.len(), 0);
let multisig1 = bls12381::Signature::aggregate(signatures1).unwrap();
let multisig2 = bls12381::Signature::aggregate(signatures2).unwrap();
let aggpk1 = PublicKey::aggregate(pubkeys1).unwrap();
let aggpk2 = PublicKey::aggregate(pubkeys2).unwrap();
assert!(multisig1.verify(&message1, &aggpk1).is_ok());
assert!(multisig2.verify(&message2, &aggpk2).is_ok());
assert!(multisig1.verify(&message1, &aggpk2).is_err());
assert!(multisig2.verify(&message2, &aggpk1).is_err());
assert!(multisig1.verify(&message2, &aggpk2).is_err());
assert!(multisig2.verify(&message1, &aggpk1).is_err());
}
#[test]
fn bls12381_random_multisig_dont_verify_with_random_pk() {
let mut rng = OsRng;
let message = random_message_for_signing(&mut rng);
let keypair = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let keypair_junk = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let signature = keypair.private_key.sign(&message);
assert!(signature.verify(&message, &keypair.public_key).is_ok());
assert!(signature
.verify(&message, &keypair_junk.public_key)
.is_err());
}
#[test]
#[ignore]
fn bls12381_sample_signature() {
let mut rng = OsRng;
let keypair = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
let sk = keypair.private_key;
let pk = keypair.public_key;
let message = b"Hello Aptos!";
let signature = sk.sign_arbitrary_message(message);
println!("SK: {}", hex::encode(&sk.to_bytes()));
println!("PK: {}", hex::encode(&pk.to_bytes()));
println!("Message: {}", std::str::from_utf8(message).unwrap());
println!("Signature: {}", hex::encode(signature.to_bytes()));
}
#[test]
fn bls12381_sample_signature_verifies() {
let pk = PublicKey::try_from(
hex::decode(
"94209a296b739577cb076d3bfb1ca8ee936f29b69b7dae436118c4dd1cc26fd43dcd16249476a006b8b949bf022a7858"
).unwrap().as_slice()
).unwrap();
let sig = bls12381::Signature::try_from(
hex::decode(
"b01ce4632e94d8c611736e96aa2ad8e0528a02f927a81a92db8047b002a8c71dc2d6bfb94729d0973790c10b6ece446817e4b7543afd7ca9a17c75de301ae835d66231c26a003f11ae26802b98d90869a9e73788c38739f7ac9d52659e1f7cf7"
).unwrap().as_slice()
).unwrap();
assert!(sig.verify_arbitrary_msg(b"Hello Aptos!", &pk).is_ok());
}
#[test]
#[ignore]
fn bls12381_sample_aggregate_pk_and_multisig() {
let mut rng = OsRng;
let num = 5;
let message = b"Hello, Aptoverse!";
let mut pks = vec![];
let mut agg_pks = vec![];
let mut sigs = vec![];
let mut multisigs = vec![];
for _i in 1..=num {
let keypair = KeyPair::<PrivateKey, PublicKey>::generate(&mut rng);
pks.push(keypair.public_key);
sigs.push(keypair.private_key.sign_arbitrary_message(message));
multisigs.push(bls12381::Signature::aggregate(sigs.clone()).unwrap());
let pk_refs = pks.iter().collect::<Vec<&PublicKey>>();
agg_pks.push(PublicKey::aggregate(pk_refs).unwrap());
}
println!("let pks = vector[");
for pk in pks {
println!(" x\"{}\",", pk);
}
println!("];\n");
println!("let agg_pks = vector[");
for aggpk in agg_pks {
println!(" x\"{}\",", aggpk);
}
println!("];\n");
println!("// The signed message is \"Hello, Aptoverse!\"");
println!("let multisigs = vector[");
for multisig in multisigs {
println!(" x\"{}\",", multisig);
}
println!("];");
}