use crate::polynomial::{Eval, PublicPoly};
use crate::tbls;
use fastcrypto::error::{FastCryptoError, FastCryptoResult};
use fastcrypto::groups::{bls12381, GroupElement, HashToGroupElement, Pairing};
use serde::{Deserialize, Serialize};
use std::num::NonZeroU16;
pub struct ThresholdBls12381MinSig {}
impl tbls::ThresholdBls for ThresholdBls12381MinSig {
type Private = bls12381::Scalar;
type Public = bls12381::G2Element;
type Signature = bls12381::G1Element;
fn verify(pk: &Self::Public, msg: &[u8], sig: &Self::Signature) -> FastCryptoResult<()> {
let hashed_message = Self::Signature::hash_to_group_element(msg);
let left = sig.pairing(&Self::Public::generator());
let right = hashed_message.pairing(pk);
match left == right {
true => Ok(()),
false => Err(FastCryptoError::InvalidSignature),
}
}
}
pub type Share = Eval<<ThresholdBls12381MinSig as tbls::ThresholdBls>::Private>;
pub type PrivateBlsKey = <ThresholdBls12381MinSig as tbls::ThresholdBls>::Private;
pub type PublicBlsKey = <ThresholdBls12381MinSig as tbls::ThresholdBls>::Public;
pub type PublicVssKey = PublicPoly<<ThresholdBls12381MinSig as tbls::ThresholdBls>::Public>;
pub type Signature = <ThresholdBls12381MinSig as tbls::ThresholdBls>::Signature;
pub type RawSignature = bls12381::G1ElementAsBytes;
pub type ShareIndex = NonZeroU16;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct IndexedValue<A> {
pub index: ShareIndex,
pub value: A,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct UnindexedValues<A> {
pub values: Vec<A>,
}
impl<A> From<Vec<IndexedValue<A>>> for UnindexedValues<A> {
fn from(index_values: Vec<IndexedValue<A>>) -> Self {
let mut values: Vec<A> = Vec::with_capacity(index_values.len());
for v in index_values {
values.push(v.value);
}
Self { values }
}
}
impl<A> UnindexedValues<A> {
pub fn add_indexes(self, indexes: &[ShareIndex]) -> FastCryptoResult<Vec<IndexedValue<A>>> {
if self.values.len() != indexes.len() {
return Err(FastCryptoError::InvalidInput);
}
let values = self
.values
.into_iter()
.zip(indexes)
.map(|(value, index)| IndexedValue {
index: *index,
value,
})
.collect();
Ok(values)
}
}