use super::{fiat_shamir::FiatShamirHash, SOUNDNESS_BYTES};
use ergotree_ir::serialization::sigma_byte_reader::SigmaByteRead;
use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWrite;
#[cfg(feature = "arbitrary")]
use proptest_derive::Arbitrary;
use std::convert::TryFrom;
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
#[derive(PartialEq, Eq, Clone)]
#[cfg(feature = "json")]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Challenge(pub(crate) FiatShamirHash);
impl std::fmt::Debug for Challenge {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
"Challenge:***".fmt(f)
}
}
impl Challenge {
pub fn secure_random() -> Self {
Self(FiatShamirHash::secure_random())
}
pub fn xor(self, other: Challenge) -> Self {
let this: [u8; SOUNDNESS_BYTES] = self.0.into();
let that: [u8; SOUNDNESS_BYTES] = other.0.into();
let res: Vec<u8> = this
.iter()
.zip(that.iter())
.map(|(&x1, &x2)| x1 ^ x2)
.collect();
#[allow(clippy::unwrap_used)] FiatShamirHash::try_from(res.as_slice()).unwrap().into()
}
pub fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> Result<(), std::io::Error> {
w.write_all(self.0 .0.as_ref())?;
Ok(())
}
pub fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, std::io::Error> {
let mut chal_bytes: [u8; super::SOUNDNESS_BYTES] = [0; super::SOUNDNESS_BYTES];
r.read_exact(&mut chal_bytes)?;
Ok(Challenge::from(FiatShamirHash(Box::new(chal_bytes))))
}
}
impl From<Challenge> for Vec<u8> {
fn from(v: Challenge) -> Self {
let arr: [u8; SOUNDNESS_BYTES] = v.0.into();
arr.to_vec()
}
}
impl From<FiatShamirHash> for Challenge {
fn from(fsh: FiatShamirHash) -> Self {
Challenge(fsh)
}
}