use alloc::vec::Vec;
use ark_ec::{
hashing::{
curve_maps::wb::{WBConfig, WBMap},
map_to_curve_hasher::{MapToCurve, MapToCurveBasedHasher},
HashToCurve,
},
pairing::{MillerLoopOutput, Pairing},
AffineRepr, CurveGroup,
};
use ark_ff::field_hashers::DefaultFieldHasher;
use sha2::Sha256;
use crate::engines::EngineBLS;
use ark_ec::bls12::Bls12Config;
use core::marker::PhantomData;
pub const QUICKNET_CTX: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_";
pub type TinyBLS381 = TinyBLSDrandQuicknet<ark_bls12_381::Bls12_381, ark_bls12_381::Config>;
pub trait CurveExtraConfig {
const CURVE_NAME: &'static [u8];
}
impl CurveExtraConfig for ark_bls12_381::Config {
const CURVE_NAME: &'static [u8] = b"BLS12381";
}
#[derive(Default)]
pub struct TinyBLSDrandQuicknet<E: Pairing, P: Bls12Config + CurveExtraConfig>(
pub E,
PhantomData<fn() -> P>,
)
where
<P as Bls12Config>::G1Config: WBConfig,
WBMap<<P as Bls12Config>::G1Config>: MapToCurve<<E as Pairing>::G1>;
impl<E: Pairing, P: Bls12Config + CurveExtraConfig> EngineBLS for TinyBLSDrandQuicknet<E, P>
where
<P as Bls12Config>::G1Config: WBConfig,
WBMap<<P as Bls12Config>::G1Config>: MapToCurve<<E as Pairing>::G1>,
{
type Engine = E;
type Scalar = <Self::Engine as Pairing>::ScalarField;
type SignatureGroup = E::G1;
type SignatureGroupAffine = E::G1Affine;
type SignaturePrepared = E::G1Prepared;
type SignatureGroupBaseField = <<E as Pairing>::G1 as CurveGroup>::BaseField;
const SIGNATURE_SERIALIZED_SIZE: usize = 48;
type PublicKeyGroup = E::G2;
type PublicKeyGroupAffine = E::G2Affine;
type PublicKeyPrepared = E::G2Prepared;
type PublicKeyGroupBaseField = <<E as Pairing>::G2 as CurveGroup>::BaseField;
const PUBLICKEY_SERIALIZED_SIZE: usize = 96;
const SECRET_KEY_SIZE: usize = 32;
const CURVE_NAME: &'static [u8] = P::CURVE_NAME;
const SIG_GROUP_NAME: &'static [u8] = b"G1";
const CIPHER_SUIT_DOMAIN_SEPARATION: &'static [u8] = b"_XMD:SHA-256_SSWU_RO_";
type HashToSignatureField = DefaultFieldHasher<Sha256, 128>;
type MapToSignatureCurve = WBMap<P::G1Config>;
fn miller_loop<'a, I>(i: I) -> MillerLoopOutput<E>
where
I: IntoIterator<Item = &'a (Self::PublicKeyPrepared, Self::SignaturePrepared)>,
{
let (i_a, i_b): (Vec<Self::PublicKeyPrepared>, Vec<Self::SignaturePrepared>) =
i.into_iter().cloned().unzip();
E::multi_miller_loop(i_b, i_a) }
fn pairing<G2, G1>(p: G2, q: G1) -> E::TargetField
where
G1: Into<E::G1Affine>,
G2: Into<E::G2Affine>,
{
E::pairing(q.into(), p.into()).0
}
fn minus_generator_of_public_key_group_prepared() -> Self::PublicKeyPrepared {
let g2_minus_generator = <Self::PublicKeyGroup as CurveGroup>::Affine::generator();
<Self::PublicKeyGroup as Into<Self::PublicKeyPrepared>>::into(
-g2_minus_generator.into_group(),
)
}
fn hash_to_curve_map() -> MapToCurveBasedHasher<
Self::SignatureGroup,
Self::HashToSignatureField,
Self::MapToSignatureCurve,
> {
MapToCurveBasedHasher::<
Self::SignatureGroup,
DefaultFieldHasher<Sha256, 128>,
WBMap<P::G1Config>,
>::new(QUICKNET_CTX)
.unwrap()
}
}