use core::fmt;
use core::iter::Sum;
use crate::{errors::InvalidPoint, secret, Curve, EncodedSecretPoint, Point};
use subtle::{Choice, ConstantTimeEq};
pub struct SecretPoint<E: Curve>(secret::Secret<Point<E>>);
impl<E: Curve> Point<E> {
#[inline(always)] pub fn into_secret(mut self) -> SecretPoint<E> {
SecretPoint::new(&mut self)
}
}
impl<E: Curve> SecretPoint<E> {
pub fn new(point: &mut Point<E>) -> Self {
Self(secret::new(point))
}
pub fn generator() -> Self {
Self::new(&mut Point::generator().into())
}
pub fn zero() -> Self {
Self::new(&mut Point::zero())
}
pub fn as_nonsecret(&self) -> &Point<E> {
secret::inner_ref(&self.0)
}
pub fn to_bytes(&self, compressed: bool) -> EncodedSecretPoint<E> {
let bytes = self.as_ref().to_bytes(compressed);
EncodedSecretPoint::new(bytes)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, InvalidPoint> {
let mut point = Point::from_bytes(bytes)?;
Ok(Self::new(&mut point))
}
}
impl<E: Curve> AsRef<Point<E>> for SecretPoint<E> {
fn as_ref(&self) -> &Point<E> {
self.as_nonsecret()
}
}
impl<E: Curve> Clone for SecretPoint<E> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<E: Curve> ConstantTimeEq for SecretPoint<E> {
fn ct_eq(&self, other: &Self) -> Choice {
self.as_ref().ct_eq(other.as_ref())
}
}
impl<E: Curve> Sum<SecretPoint<E>> for Point<E> {
fn sum<I: Iterator<Item = SecretPoint<E>>>(iter: I) -> Self {
iter.fold(Point::<E>::zero(), |acc, i| acc + &i)
}
}
impl<'s, E: Curve> Sum<&'s SecretPoint<E>> for Point<E> {
fn sum<I: Iterator<Item = &'s SecretPoint<E>>>(iter: I) -> Self {
iter.fold(Point::<E>::zero(), |acc, i| acc + i)
}
}
impl<E: Curve> fmt::Debug for SecretPoint<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SecretPoint")
}
}