use bacteria::Transcript;
use mohan::dalek::{ristretto::CompressedRistretto, scalar::Scalar};
use crate::{
errors::MuSigError, MuSigContext, MultiKey, Multimessage, Multisignature, PublicKey, SecretKey,
Signature, Signer,
};
#[test]
fn sign_verify_single_multikey() {
let privkey = SecretKey::from_scalar(Scalar::from(1u64));
let privkeys = vec![privkey];
let multikey = multikey_helper(&privkeys);
let (sig, _) = sign_with_mpc(
&privkeys,
multikey.clone(),
Transcript::new(b"example transcript"),
)
.unwrap();
assert!(sig
.verify(
&mut Transcript::new(b"example transcript"),
&multikey.aggregated_key()
)
.is_ok());
}
fn multikey_helper(priv_keys: &Vec<SecretKey>) -> MultiKey {
MultiKey::new(
priv_keys
.iter()
.map(|priv_key| PublicKey::from_secret(priv_key))
.collect(),
)
.unwrap()
}
#[test]
fn sign_multikey() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let multikey = multikey_helper(&priv_keys);
assert!(sign_with_mpc(&priv_keys, multikey, Transcript::new(b"example transcript")).is_ok());
}
fn sign_with_mpc<C: MuSigContext + Clone>(
privkeys: &Vec<SecretKey>,
context: C,
transcript: Transcript,
) -> Result<(Signature, Scalar), MuSigError> {
let pubkeys: Vec<_> = privkeys
.iter()
.map(|privkey| PublicKey::from_secret(privkey))
.collect();
let mut transcripts: Vec<_> = pubkeys.iter().map(|_| transcript.clone()).collect();
let (parties, precomms): (Vec<_>, Vec<_>) = privkeys
.clone()
.into_iter()
.zip(transcripts.iter_mut())
.enumerate()
.map(|(i, (x_i, transcript))| Signer::new(transcript, i, x_i.to_scalar(), context.clone()))
.unzip();
let (parties, comms): (Vec<_>, Vec<_>) = parties
.into_iter()
.map(|p| p.receive_precommitments(precomms.clone()))
.unzip();
let (parties, shares): (Vec<_>, Vec<_>) = parties
.into_iter()
.map(|p| p.receive_commitments(comms.clone()).unwrap())
.unzip();
let signatures: Vec<Signature> = parties
.into_iter()
.map(|p| p.receive_shares(shares.clone()).unwrap())
.collect();
let cmp = &signatures[0];
for sig in &signatures {
assert_eq!(cmp.s, sig.s);
assert_eq!(cmp.R, sig.R)
}
let cmp_challenge = transcripts[0].clone().challenge_scalar(b"test");
for mut transcript in transcripts {
let challenge = transcript.challenge_scalar(b"test");
assert_eq!(cmp_challenge, challenge);
}
Ok((signatures[0].clone(), cmp_challenge))
}
#[test]
fn verify_multikey() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let multikey = multikey_helper(&priv_keys);
let (signature, _) = sign_with_mpc(
&priv_keys,
multikey.clone(),
Transcript::new(b"example transcript"),
)
.unwrap();
assert!(signature
.verify(
&mut Transcript::new(b"example transcript"),
&multikey.aggregated_key()
)
.is_ok());
}
#[test]
fn check_transcripts_multikey() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let multikey = multikey_helper(&priv_keys);
let (signature, prover_challenge) = sign_with_mpc(
&priv_keys,
multikey.clone(),
Transcript::new(b"example transcript"),
)
.unwrap();
let verifier_transcript = &mut Transcript::new(b"example transcript");
assert!(signature
.verify(verifier_transcript, &multikey.aggregated_key())
.is_ok());
let verifier_challenge = verifier_transcript.challenge_scalar(b"test");
assert_eq!(prover_challenge, verifier_challenge);
}
#[test]
fn sign_multimessage() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let messages = vec![b"message1", b"message2", b"message3", b"message4"];
let multimessage = Multimessage::new(multimessage_helper(&priv_keys, messages));
assert!(sign_with_mpc(
&priv_keys,
multimessage,
Transcript::new(b"example transcript")
)
.is_ok());
}
fn multimessage_helper<M: AsRef<[u8]>>(
priv_keys: &Vec<SecretKey>,
messages: Vec<M>,
) -> Vec<(PublicKey, M)> {
priv_keys
.iter()
.zip(messages.into_iter())
.map(|(priv_key, msg)| (PublicKey::from_secret(priv_key), msg))
.collect()
}
#[test]
fn verify_multimessage_mpc() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let messages = vec![b"message1", b"message2", b"message3", b"message4"];
let multimessage = Multimessage::new(multimessage_helper(&priv_keys, messages.clone()));
let (signature, _) = sign_with_mpc(
&priv_keys,
multimessage.clone(),
Transcript::new(b"example transcript"),
)
.unwrap();
assert!(signature
.verify_multi(
&mut Transcript::new(b"example transcript"),
multimessage_helper(&priv_keys, messages)
)
.is_ok());
}
#[test]
fn verify_multimessage_singleplayer() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let messages = vec![b"message1", b"message2", b"message3", b"message4"];
let pairs = multimessage_helper(&priv_keys, messages.clone());
let signature = Signature::sign_multi(
priv_keys.clone(),
pairs,
&mut Transcript::new(b"example transcript"),
)
.unwrap();
assert!(signature
.verify_multi(
&mut Transcript::new(b"example transcript"),
multimessage_helper(&priv_keys, messages)
)
.is_ok());
}
#[test]
fn check_transcripts_multimessage() {
let priv_keys = vec![
SecretKey::from_scalar(Scalar::from(1u64)),
SecretKey::from_scalar(Scalar::from(2u64)),
SecretKey::from_scalar(Scalar::from(3u64)),
SecretKey::from_scalar(Scalar::from(4u64)),
];
let messages = vec![b"message1", b"message2", b"message3", b"message4"];
let multimessage = Multimessage::new(multimessage_helper(&priv_keys, messages.clone()));
let (signature, prover_challenge) = sign_with_mpc(
&priv_keys,
multimessage.clone(),
Transcript::new(b"example transcript"),
)
.unwrap();
let verifier_transcript = &mut Transcript::new(b"example transcript");
assert!(signature
.verify_multi(
verifier_transcript,
multimessage_helper(&priv_keys, messages)
)
.is_ok());
let verifier_challenge = verifier_transcript.challenge_scalar(b"test");
assert_eq!(prover_challenge, verifier_challenge);
}