use core::fmt::{Formatter, Debug};
use curve25519_dalek::constants::{RISTRETTO_BASEPOINT_TABLE, RISTRETTO_BASEPOINT_POINT};
use curve25519_dalek::ristretto::RistrettoPoint;
use curve25519_dalek::scalar::Scalar;
use curve25519_dalek::traits::MultiscalarMul;
use rand_core::{RngCore, CryptoRng};
#[cfg(feature = "enable-serde")]
use serde::{Serialize, Deserialize};
use crate::{Ciphertext, DecryptionKey};
#[derive(Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct EncryptionKey(pub(crate) RistrettoPoint);
impl EncryptionKey {
pub fn exp_encrypt<R: RngCore + CryptoRng>(&self, m: Scalar, rng: &mut R) -> Ciphertext {
self.exp_encrypt_with(m, Scalar::random(rng))
}
pub fn exp_encrypt_with(&self, m: Scalar, r: Scalar) -> Ciphertext {
let c1 = &r * &RISTRETTO_BASEPOINT_TABLE;
let c2 = RistrettoPoint::multiscalar_mul(&[m, r], &[RISTRETTO_BASEPOINT_POINT, self.0]);
Ciphertext(c1, c2)
}
pub fn encrypt<R: RngCore + CryptoRng>(&self, m: RistrettoPoint, rng: &mut R) -> Ciphertext {
self.encrypt_with(m, Scalar::random(rng))
}
pub fn encrypt_with(&self, m: RistrettoPoint, r: Scalar) -> Ciphertext {
let c1 = &r * &RISTRETTO_BASEPOINT_TABLE;
let c2 = m + r * &self.0;
Ciphertext(c1, c2)
}
pub fn rerandomise<R: RngCore + CryptoRng>(&self, ct: Ciphertext, rng: &mut R) -> Ciphertext {
self.rerandomise_with(ct, Scalar::random(rng))
}
pub fn rerandomise_with(&self, ct: Ciphertext, r: Scalar) -> Ciphertext {
let c1 = ct.0 + &r * &RISTRETTO_BASEPOINT_TABLE;
let c2 = ct.1 + &self.0 * r;
Ciphertext(c1, c2)
}
}
impl Debug for EncryptionKey {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "EncryptionKey({:?})", self.0.compress())
}
}
impl From<DecryptionKey> for EncryptionKey {
fn from(dk: DecryptionKey) -> Self {
dk.ek
}
}
impl From<RistrettoPoint> for EncryptionKey {
fn from(y: RistrettoPoint) -> Self {
Self(y)
}
}
impl AsRef<RistrettoPoint> for EncryptionKey {
fn as_ref(&self) -> &RistrettoPoint {
&self.0
}
}