use blsful::*;
use rand::{Rng, SeedableRng, TryRng, rand_core::Infallible};
use rstest::*;
use serde::{Deserialize, Serialize, de::DeserializeOwned};
const TEST_MSG: &[u8] = b"signatures_work";
struct MockRng(rand_xorshift::XorShiftRng);
impl SeedableRng for MockRng {
type Seed = [u8; 16];
fn from_seed(seed: Self::Seed) -> Self {
Self(rand_xorshift::XorShiftRng::from_seed(seed))
}
}
impl rand::TryCryptoRng for MockRng {}
impl TryRng for MockRng {
type Error = Infallible;
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
Ok(self.0.next_u32())
}
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
Ok(self.0.next_u64())
}
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
self.0.fill_bytes(dest);
Ok(())
}
}
impl Default for MockRng {
fn default() -> Self {
Self(rand_xorshift::XorShiftRng::from_seed([7u8; 16]))
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Document<T> {
value: T,
}
fn assert_required_format_roundtrips<T>(value: &T)
where
T: Serialize + DeserializeOwned + PartialEq + std::fmt::Debug + 'static,
{
let postcard = postcard::to_allocvec(value).expect("postcard serialization succeeds");
let postcard_value =
postcard::from_bytes::<T>(&postcard).expect("postcard deserialization succeeds");
assert_eq!(value, &postcard_value);
let mut cbor = Vec::new();
ciborium::into_writer(value, &mut cbor).expect("CBOR serialization succeeds");
let cbor_value =
ciborium::from_reader::<T, _>(cbor.as_slice()).expect("CBOR deserialization succeeds");
assert_eq!(value, &cbor_value);
let json = serde_json::to_vec(value).expect("JSON serialization succeeds");
let json_value = serde_json::from_slice::<T>(&json).expect("JSON deserialization succeeds");
assert_eq!(value, &json_value);
let toml = toml::to_string(&Document { value }).expect("TOML serialization succeeds");
let toml_value = toml::from_str::<Document<T>>(&toml).expect("TOML deserialization succeeds");
assert_eq!(value, &toml_value.value);
let yaml = noyalib::to_string(value).expect("YAML serialization succeeds");
let yaml_value = noyalib::from_str::<T>(&yaml).expect("YAML deserialization succeeds");
assert_eq!(value, &yaml_value);
}
#[rstest]
#[case::g1(Bls12381G1Impl)]
#[case::g2(Bls12381G2Impl)]
fn basic_types_serialize_required_formats<
C: BlsSignatureImpl + PartialEq + Eq + std::fmt::Debug + 'static,
>(
#[case] _c: C,
) {
let sk = SecretKey::<C>::random(MockRng::default());
let pk = sk.public_key();
let sig = sk
.sign(SignatureSchemes::ProofOfPossession, TEST_MSG)
.unwrap();
assert_required_format_roundtrips(&sk);
assert_required_format_roundtrips(&pk);
assert_required_format_roundtrips(&sig);
}
#[rstest]
#[case::g1(Bls12381G1Impl)]
#[case::g2(Bls12381G2Impl)]
fn basic_types_serialize_json<C: BlsSignatureImpl + PartialEq + Eq + std::fmt::Debug>(
#[case] _c: C,
) {
let sk = SecretKey::<C>::random(MockRng::default());
let pk = sk.public_key();
let sig_b = sk.sign(SignatureSchemes::Basic, TEST_MSG).unwrap();
let sig_ma = sk
.sign(SignatureSchemes::MessageAugmentation, TEST_MSG)
.unwrap();
let sig_pop = sk
.sign(SignatureSchemes::ProofOfPossession, TEST_MSG)
.unwrap();
let res = serde_json::to_vec(&sk);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<SecretKey<C>>(&text);
assert!(res.is_ok());
let sk2 = res.unwrap();
assert_eq!(sk, sk2);
let res = serde_json::to_vec(&pk);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<PublicKey<C>>(&text);
assert!(res.is_ok());
let pk2 = res.unwrap();
assert_eq!(pk, pk2);
let res = serde_json::to_vec(&sig_b);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_b2 = res.unwrap();
assert_eq!(sig_b, sig_b2);
let res = serde_json::to_vec(&sig_ma);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_ma2 = res.unwrap();
assert_eq!(sig_ma, sig_ma2);
let res = serde_json::to_vec(&sig_pop);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_pop2 = res.unwrap();
assert_eq!(sig_pop, sig_pop2);
}
#[rstest]
#[case::g1(Bls12381G1Impl)]
#[case::g2(Bls12381G2Impl)]
fn basic_types_serialize_binary<C: BlsSignatureImpl + PartialEq + Eq + std::fmt::Debug>(
#[case] _c: C,
) {
let sk = SecretKey::<C>::random(MockRng::default());
let pk = sk.public_key();
let sig_b = sk.sign(SignatureSchemes::Basic, TEST_MSG).unwrap();
let sig_ma = sk
.sign(SignatureSchemes::MessageAugmentation, TEST_MSG)
.unwrap();
let sig_pop = sk
.sign(SignatureSchemes::ProofOfPossession, TEST_MSG)
.unwrap();
let res = serde_bare::to_vec(&sk);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_bare::from_slice::<SecretKey<C>>(&text);
assert!(res.is_ok());
let sk2 = res.unwrap();
assert_eq!(sk, sk2);
let res = serde_bare::to_vec(&pk);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_bare::from_slice::<PublicKey<C>>(&text);
assert!(res.is_ok());
let pk2 = res.unwrap();
assert_eq!(pk, pk2);
let res = serde_bare::to_vec(&sig_b);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_bare::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_b2 = res.unwrap();
assert_eq!(sig_b, sig_b2);
let res = serde_bare::to_vec(&sig_ma);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_bare::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_ma2 = res.unwrap();
assert_eq!(sig_ma, sig_ma2);
let res = serde_bare::to_vec(&sig_pop);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_bare::from_slice::<Signature<C>>(&text);
assert!(res.is_ok());
let sig_pop2 = res.unwrap();
assert_eq!(sig_pop, sig_pop2);
}
#[rstest]
#[case::g1(Bls12381G1Impl)]
#[case::g2(Bls12381G2Impl)]
fn shares_serialize<
C: BlsSignatureImpl
+ PartialEq
+ Eq
+ std::fmt::Debug
+ serde::Serialize
+ serde::de::DeserializeOwned
+ 'static,
>(
#[case] _c: C,
) {
let sk = SecretKey::<C>::from_hash(b"shares_serialize_json");
let sk_shares = sk.split(10, 20).unwrap();
for share in &sk_shares {
assert_required_format_roundtrips(share);
let text = serde_json::to_vec(&share).unwrap_or_else(|e| panic!("{e:?}"));
let share2 =
serde_json::from_slice::<SecretKeyShare<C>>(&text).unwrap_or_else(|e| panic!("{e:?}"));
assert_eq!(share, &share2);
let text = serde_bare::to_vec(&share).unwrap_or_else(|e| panic!("{e:?}"));
let share2 =
serde_bare::from_slice::<SecretKeyShare<C>>(&text).unwrap_or_else(|e| panic!("{e:?}"));
assert_eq!(share, &share2);
let pks = share.public_key().unwrap();
assert_required_format_roundtrips(&pks);
let text = serde_json::to_vec(&pks).unwrap_or_else(|e| panic!("{e:?}"));
let pks2 =
serde_json::from_slice::<PublicKeyShare<C>>(&text).unwrap_or_else(|e| panic!("{e:?}"));
assert_eq!(pks, pks2);
let sgs = share
.sign(SignatureSchemes::ProofOfPossession, TEST_MSG)
.unwrap();
assert_required_format_roundtrips(&sgs);
let res = serde_json::to_vec(&sgs);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<SignatureShare<C>>(&text);
assert!(res.is_ok());
let sgs2 = res.unwrap();
assert_eq!(sgs, sgs2);
}
}
#[test]
fn shares_serialize_test() {
let sk = SecretKey::<Bls12381G1Impl>::from_hash(b"shares_serialize_json");
let sk_shares = sk.split(10, 20).unwrap();
for share in &sk_shares {
let text = serde_json::to_vec(&share).unwrap_or_else(|e| panic!("{e:?}"));
let share2 = serde_json::from_slice::<SecretKeyShare<Bls12381G1Impl>>(&text)
.unwrap_or_else(|e| panic!("{e:?}"));
assert_eq!(share, &share2);
let pks = share.public_key().unwrap();
let text = serde_json::to_vec(&pks).unwrap_or_else(|e| panic!("{e:?}"));
let pks2 = serde_json::from_slice::<PublicKeyShare<Bls12381G1Impl>>(&text)
.unwrap_or_else(|e| panic!("{e:?}"));
assert_eq!(pks, pks2);
let sgs = share
.sign(SignatureSchemes::ProofOfPossession, TEST_MSG)
.unwrap();
let res = serde_json::to_vec(&sgs);
assert!(res.is_ok());
let text = res.unwrap();
let res = serde_json::from_slice::<SignatureShare<Bls12381G1Impl>>(&text);
assert!(res.is_ok());
let sgs2 = res.unwrap();
assert_eq!(sgs, sgs2);
}
}