use crate::base::sig::ClsagSig;
use crate::crypto::{
Point, Scalar, clsag::ClsagGgxInputRef, compute_key_image, generate_clsag_ggx,
};
use crate::error::Result;
use crate::rng::RngCore;
pub struct ClsagRequest<'a> {
pub hi: &'a Scalar,
pub msg: &'a [u8],
pub ring: &'a [ClsagGgxInputRef],
pub key_image: &'a Point,
pub pseudo_out_amount_commitment: &'a Point,
pub pseudo_out_blinded_asset_id: &'a Point,
pub secret1_f: &'a Scalar,
pub secret2_t: &'a Scalar,
pub secret_index: u64,
}
pub trait InputSigner {
fn key_image(&mut self, hi: &Scalar, in_e_pub: &Point) -> Result<Point>;
fn sign_clsag(&mut self, rnd: &mut dyn RngCore, req: &ClsagRequest<'_>) -> Result<ClsagSig>;
}
pub struct LocalInputSigner {
spend_secret: Scalar,
}
impl LocalInputSigner {
pub fn new(spend_secret: Scalar) -> LocalInputSigner {
LocalInputSigner { spend_secret }
}
fn in_e_sec(&self, hi: &Scalar) -> Scalar {
hi.add(&self.spend_secret)
}
}
impl InputSigner for LocalInputSigner {
fn key_image(&mut self, hi: &Scalar, in_e_pub: &Point) -> Result<Point> {
Ok(compute_key_image(&self.in_e_sec(hi), in_e_pub))
}
fn sign_clsag(&mut self, rnd: &mut dyn RngCore, req: &ClsagRequest<'_>) -> Result<ClsagSig> {
generate_clsag_ggx(
rnd,
req.msg,
req.ring,
req.key_image,
req.pseudo_out_amount_commitment,
req.pseudo_out_blinded_asset_id,
&self.in_e_sec(req.hi),
req.secret1_f,
req.secret2_t,
req.secret_index,
)
}
}