use crate::{group::edwards25519::CurveError, Group, Point, Random, Scalar};
use core::fmt::{Debug, Display, Formatter};
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub trait Generator<SCALAR: Scalar> {
fn new_key<S: crate::cipher::Stream>(&self, stream: &mut S)
-> Result<Option<SCALAR>, KeyError>;
}
pub trait Suite: Group + Random {}
#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pair<POINT: Point> {
#[serde(deserialize_with = "POINT::deserialize")]
pub public: POINT, pub private: POINT::SCALAR, }
impl<POINT: Point> Debug for Pair<POINT> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Pair")
.field("public", &self.public)
.finish()
}
}
impl<POINT: Point> Display for Pair<POINT> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "Pair( public_key: {} )", self.public)
}
}
pub fn new_key_pair<SUITE: Suite + Generator<<SUITE::POINT as Point>::SCALAR>>(
suite: &SUITE,
) -> Result<Pair<SUITE::POINT>, KeyError> {
let mut kp = Pair::default();
kp.gen(suite)?;
Ok(kp)
}
impl<POINT: Point> Pair<POINT> {
pub(crate) fn gen<SUITE: Suite<POINT = POINT> + Generator<POINT::SCALAR>>(
&mut self,
suite: &SUITE,
) -> Result<(), KeyError> {
let mut random = suite.random_stream();
self.private = match suite.new_key(&mut random)? {
Some(key) => key,
None => suite.scalar().pick(&mut random),
};
self.public = suite.point().mul(&self.private, None);
Ok(())
}
}
#[derive(Error, Debug)]
pub enum KeyError {
#[error("curve error")]
CurveError(#[from] CurveError),
}