use snarkvm_utilities::{FromBytes, ToBytes};
use anyhow::Result;
use rand::{CryptoRng, Rng};
use std::{fmt::Debug, hash::Hash};
pub trait SignatureScheme:
Sized + ToBytes + FromBytes + Debug + Clone + Eq + Send + Sync + From<<Self as SignatureScheme>::Parameters>
{
type Parameters: Clone + Debug + Eq;
type PublicKey: Clone + Debug + Default + ToBytes + FromBytes + Hash + Eq + Send + Sync;
type PrivateKey: Clone + Debug + Default + ToBytes + FromBytes + PartialEq + Eq;
type Signature: Clone + Debug + Default + ToBytes + FromBytes + Send + Sync + PartialEq + Eq;
fn setup(message: &str) -> Self;
fn parameters(&self) -> &Self::Parameters;
fn generate_private_key<R: Rng + CryptoRng>(&self, rng: &mut R) -> Self::PrivateKey;
fn generate_public_key(&self, private_key: &Self::PrivateKey) -> Self::PublicKey;
fn sign<R: Rng + CryptoRng>(
&self,
private_key: &Self::PrivateKey,
message: &[u8],
rng: &mut R,
) -> Result<Self::Signature>;
fn verify(&self, public_key: &Self::PublicKey, message: &[u8], signature: &Self::Signature) -> Result<bool>;
}
pub trait SignatureSchemeOperations {
type AffineCurve: Clone + Debug + Default + ToBytes + FromBytes + Hash + Eq + Send + Sync;
type BaseField: Clone + Debug + Default + ToBytes + FromBytes + PartialEq + Eq;
type ScalarField: Clone + Debug + Default + ToBytes + FromBytes + PartialEq + Eq;
type Signature: Clone + Debug + Default + ToBytes + FromBytes + PartialEq + Eq;
fn pk_sig(signature: &Self::Signature) -> Result<Self::AffineCurve>;
fn pr_sig(signature: &Self::Signature) -> Result<Self::AffineCurve>;
fn g_scalar_multiply(&self, scalar: &Self::ScalarField) -> Self::AffineCurve;
fn hash_to_scalar_field(&self, input: &[Self::BaseField]) -> Self::ScalarField;
}