use alloc::sync::Arc;
use curve25519_dalek::{RistrettoPoint, Scalar};
use rand_core::CryptoRngCore;
use snafu::prelude::*;
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
use crate::TriptychParameters;
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct TriptychWitness {
#[zeroize(skip)]
params: Arc<TriptychParameters>,
l: u32,
r: Scalar,
}
#[derive(Debug, Snafu)]
pub enum WitnessError {
#[snafu(display("An invalid parameter was provided"))]
InvalidParameter,
}
impl TriptychWitness {
#[allow(non_snake_case)]
pub fn new(params: &Arc<TriptychParameters>, l: u32, r: &Scalar) -> Result<Self, WitnessError> {
if r == &Scalar::ZERO {
return Err(WitnessError::InvalidParameter);
}
if l >= params.get_N() {
return Err(WitnessError::InvalidParameter);
}
Ok(Self {
params: params.clone(),
l,
r: *r,
})
}
#[allow(clippy::cast_possible_truncation)]
pub fn random<R: CryptoRngCore>(params: &Arc<TriptychParameters>, rng: &mut R) -> Self {
#[allow(clippy::arithmetic_side_effects)]
let l = (rng.as_rngcore().next_u64() % u64::from(params.get_N())) as u32;
Self {
params: params.clone(),
l,
r: Scalar::random(rng),
}
}
pub fn get_params(&self) -> &Arc<TriptychParameters> {
&self.params
}
pub fn get_l(&self) -> u32 {
self.l
}
pub fn get_r(&self) -> &Scalar {
&self.r
}
#[allow(non_snake_case)]
pub fn compute_linking_tag(&self) -> RistrettoPoint {
*Zeroizing::new(self.r.invert()) * self.params.get_U()
}
pub fn compute_verification_key(&self) -> RistrettoPoint {
self.r * self.params.get_G()
}
}