use core::{borrow::Borrow, ops::MulAssign};
use alloc::{vec, vec::Vec};
use ark_ec::{
hashing::{
map_to_curve_hasher::{MapToCurve, MapToCurveBasedHasher},
HashToCurve,
},
pairing::{MillerLoopOutput, Pairing, PairingOutput},
AffineRepr, CurveGroup,
};
use ark_ff::{field_hashers::HashToField, Field, PrimeField, UniformRand};
use ark_serialize::CanonicalSerialize;
use ark_std::rand::RngCore;
use rand::Rng;
use core::fmt::Debug;
pub trait EngineBLS {
type Engine: Pairing;
type Scalar: PrimeField;
type PublicKeyGroupBaseField: Field;
type PublicKeyGroupAffine: AffineRepr<ScalarField = Self::Scalar, Group = Self::PublicKeyGroup>
+ From<Self::PublicKeyGroup>
+ Into<Self::PublicKeyGroup>
+ Into<Self::PublicKeyPrepared>;
type PublicKeyGroup: CurveGroup<
Affine = Self::PublicKeyGroupAffine,
ScalarField = Self::Scalar,
BaseField = Self::PublicKeyGroupBaseField,
> + From<Self::PublicKeyGroupAffine>
+ Into<Self::PublicKeyGroupAffine>
+ MulAssign<Self::Scalar>;
type PublicKeyPrepared: Default + Clone + Send + Sync + Debug + From<Self::PublicKeyGroupAffine>;
const PUBLICKEY_SERIALIZED_SIZE: usize;
const SECRET_KEY_SIZE: usize;
const CURVE_NAME: &'static [u8];
const SIG_GROUP_NAME: &'static [u8];
const CIPHER_SUIT_DOMAIN_SEPARATION: &'static [u8];
type SignatureGroupBaseField: Field;
type SignatureGroupAffine: AffineRepr<ScalarField = Self::Scalar, Group = Self::SignatureGroup>
+ From<Self::SignatureGroup>
+ Into<Self::SignatureGroup>
+ Into<Self::SignaturePrepared>;
type SignatureGroup: CurveGroup<
Affine = Self::SignatureGroupAffine,
ScalarField = Self::Scalar,
BaseField = Self::SignatureGroupBaseField,
> + Into<Self::SignatureGroupAffine>
+ From<Self::SignatureGroupAffine>
+ MulAssign<Self::Scalar>;
type SignaturePrepared: Default + Clone + Send + Sync + Debug + From<Self::SignatureGroupAffine>;
const SIGNATURE_SERIALIZED_SIZE: usize;
type HashToSignatureField: HashToField<Self::SignatureGroupBaseField>;
type MapToSignatureCurve: MapToCurve<Self::SignatureGroup>;
fn generate<R: Rng + RngCore>(rng: &mut R) -> Self::Scalar {
Self::Scalar::rand(rng)
}
fn hash_to_curve_map() -> MapToCurveBasedHasher<
Self::SignatureGroup,
Self::HashToSignatureField,
Self::MapToSignatureCurve,
>;
fn hash_to_signature_curve<M: Borrow<[u8]>>(message: M) -> Self::SignatureGroup {
Self::hash_to_curve_map().hash(message.borrow()).unwrap().into_group()
}
fn miller_loop<'a, I>(i: I) -> MillerLoopOutput<Self::Engine>
where
Self::PublicKeyPrepared: 'a,
Self::SignaturePrepared: 'a,
I: IntoIterator<
Item = &'a (<Self as EngineBLS>::PublicKeyPrepared, Self::SignaturePrepared),
>;
fn final_exponentiation(
e: MillerLoopOutput<Self::Engine>,
) -> Option<PairingOutput<Self::Engine>> {
Self::Engine::final_exponentiation(e)
}
fn pairing<G1, G2>(p: G1, q: G2) -> <Self::Engine as Pairing>::TargetField
where
G1: Into<<Self::PublicKeyGroup as CurveGroup>::Affine>,
G2: Into<<Self::SignatureGroup as CurveGroup>::Affine>;
fn minus_generator_of_public_key_group_prepared() -> Self::PublicKeyPrepared;
fn generator_of_signature_group() -> Self::SignatureGroup {
<Self::SignatureGroup as CurveGroup>::Affine::generator().into()
}
fn prepare_public_key(g: impl Into<Self::PublicKeyGroupAffine>) -> Self::PublicKeyPrepared {
let g_affine: Self::PublicKeyGroupAffine = g.into();
Self::PublicKeyPrepared::from(g_affine)
}
fn prepare_signature(g: impl Into<Self::SignatureGroupAffine>) -> Self::SignaturePrepared {
let g_affine: Self::SignatureGroupAffine = g.into();
Self::SignaturePrepared::from(g_affine)
}
fn signature_point_to_byte(point: &Self::SignatureGroup) -> Vec<u8> {
let mut point_as_bytes = vec![0; Self::SIGNATURE_SERIALIZED_SIZE];
let point_affine = point.into_affine();
point_affine.serialize_compressed(&mut point_as_bytes[..]).unwrap();
point_as_bytes
}
fn public_key_point_to_byte(point: &Self::PublicKeyGroup) -> Vec<u8> {
let mut point_as_bytes = vec![0; Self::PUBLICKEY_SERIALIZED_SIZE];
let point_affine = point.into_affine();
point_affine.serialize_compressed(&mut point_as_bytes[..]).unwrap();
point_as_bytes
}
}