mod g1;
mod g2;
pub use g1::*;
pub use g2::*;
use crate::*;
use core::{
fmt::{self, Display, Formatter},
marker::PhantomData,
str::FromStr,
};
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
pub trait BlsSignatureImpl:
BlsSignatureBasic + BlsSignatureMessageAugmentation + BlsSignaturePop
{
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub struct BlsSignature<T: BlsSignatureImpl>(PhantomData<T>);
impl Default for BlsSignature<Bls12381G1Impl> {
fn default() -> Self {
BlsSignature(PhantomData)
}
}
impl<T: BlsSignatureImpl> BlsSignature<T> {
pub fn new() -> Self {
BlsSignature(PhantomData)
}
pub fn new_secret_key() -> SecretKey<T> {
SecretKey::random(get_crypto_rng())
}
pub fn secret_key_from_hash<B: AsRef<[u8]>>(data: B) -> SecretKey<T> {
SecretKey(<T as HashToScalar>::hash_to_scalar(
data.as_ref(),
KEYGEN_SALT,
))
}
pub fn random_secret_key(mut rng: impl RngCore + CryptoRng) -> SecretKey<T> {
SecretKey(<T as HashToScalar>::hash_to_scalar(
rng.r#gen::<[u8; SECRET_KEY_BYTES]>(),
KEYGEN_SALT,
))
}
pub fn new_proof_challenge() -> ProofCommitmentChallenge<T> {
ProofCommitmentChallenge::new()
}
pub fn proof_challenge_from_hash<B: AsRef<[u8]>>(data: B) -> ProofCommitmentChallenge<T> {
ProofCommitmentChallenge::from_hash(data)
}
pub fn random_proof_challenge(
mut rng: impl RngCore + CryptoRng,
) -> ProofCommitmentChallenge<T> {
ProofCommitmentChallenge::random(&mut rng)
}
}
pub type Bls12381G1 = BlsSignature<Bls12381G1Impl>;
pub type Bls12381G2 = BlsSignature<Bls12381G2Impl>;
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Bls12381 {
#[default]
G1,
G2,
}
impl From<Bls12381> for u8 {
fn from(bls: Bls12381) -> u8 {
match bls {
Bls12381::G1 => 1,
Bls12381::G2 => 2,
}
}
}
impl From<&Bls12381> for u8 {
fn from(bls: &Bls12381) -> u8 {
u8::from(*bls)
}
}
impl TryFrom<u8> for Bls12381 {
type Error = BlsError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
1 => Ok(Bls12381::G1),
2 => Ok(Bls12381::G2),
_ => Err(BlsError::DeserializationError(
"Invalid BLS12381 type".to_string(),
)),
}
}
}
impl TryFrom<&u8> for Bls12381 {
type Error = BlsError;
fn try_from(value: &u8) -> Result<Self, Self::Error> {
Self::try_from(*value)
}
}
impl Display for Bls12381 {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Bls12381::G1 => write!(f, "BLS12381G1"),
Bls12381::G2 => write!(f, "BLS12381G2"),
}
}
}
impl FromStr for Bls12381 {
type Err = BlsError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BLS12381G1" => Ok(Bls12381::G1),
"BLS12381G2" => Ok(Bls12381::G2),
_ => Err(BlsError::DeserializationError(
"Invalid BLS12381 type".to_string(),
)),
}
}
}
impl Serialize for Bls12381 {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
if s.is_human_readable() {
s.serialize_str(&self.to_string())
} else {
s.serialize_u8(u8::from(self))
}
}
}
impl<'de> Deserialize<'de> for Bls12381 {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
if d.is_human_readable() {
let s = String::deserialize(d)?;
Bls12381::from_str(&s).map_err(serde::de::Error::custom)
} else {
let u = u8::deserialize(d)?;
Bls12381::try_from(u).map_err(serde::de::Error::custom)
}
}
}
pub mod inner_types {
#[cfg(not(feature = "blst"))]
pub use bls12_381_plus::{
Bls12, Bls12381G1 as InnerBls12381G1, Bls12381G2 as InnerBls12381G2, G1Affine,
G1Projective, G2Affine, G2Prepared, G2Projective, Gt, MillerLoopResult, Scalar, ScalarLe,
elliptic_curve::hash2curve::{
ExpandMsg, ExpandMsgXmd, ExpandMsgXof, Expander, ExpanderXmd,
},
ff::{Field, FieldBits, FromUniformBytes, PrimeField, PrimeFieldBits},
group::{
Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned, ScalarMul, ScalarMulOwned,
UncompressedEncoding, cofactor::*, prime::*,
},
multi_miller_loop, pairing,
};
#[cfg(feature = "blst")]
pub use blstrs_plus::{
Bls12, Bls12381G1 as InnerBls12381G1, Bls12381G2 as InnerBls12381G2, G1Affine,
G1Compressed, G1Projective, G2Affine, G2Compressed, G2Prepared, G2Projective, Gt, Scalar,
elliptic_curve::hash2curve::{
ExpandMsg, ExpandMsgXmd, ExpandMsgXof, Expander, ExpanderXmd,
},
ff::{Field, FieldBits, FromUniformBytes, PrimeField, PrimeFieldBits},
group::{
Curve, Group, GroupEncoding, GroupOps, GroupOpsOwned, ScalarMul, ScalarMulOwned,
UncompressedEncoding, cofactor::*, prime::*,
},
multi_miller_loop, pairing,
pairing_lib::{Engine, MillerLoopResult, MultiMillerLoop, PairingCurveAffine},
};
}