use alloc::{string::ToString, vec::Vec};
use core::{fmt, marker::PhantomData, ops::Deref};
use num::Zero;
use super::{
super::{FALCON_ENCODING_BITS, FalconVariant, LOG_N, N, PK_LEN},
ByteReader, ByteWriter, Deserializable, DeserializationError, FalconFelt, Felt, Polynomial,
Serializable, Signature,
};
use crate::{SequentialCommit, Word};
#[derive(Clone, PartialEq, Eq)]
pub struct PublicKey<V: FalconVariant>(Polynomial<FalconFelt>, PhantomData<fn() -> V>);
impl<V: FalconVariant> PublicKey<V> {
pub fn verify(&self, message: Word, signature: &Signature<V>) -> bool {
signature.verify(message, self)
}
pub fn recover_from(_message: Word, signature: &Signature<V>) -> Self {
signature.public_key().clone()
}
pub fn to_commitment(&self) -> Word {
<Self as SequentialCommit>::to_commitment(self)
}
}
impl<V: FalconVariant> SequentialCommit for PublicKey<V> {
type Commitment = Word;
fn to_commitment(&self) -> Self::Commitment {
V::public_key_commitment(&self.to_elements())
}
fn to_elements(&self) -> Vec<Felt> {
Into::<Polynomial<Felt>>::into(self.0.clone()).coefficients
}
}
impl<V: FalconVariant> Deref for PublicKey<V> {
type Target = Polynomial<FalconFelt>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<V: FalconVariant> From<Polynomial<FalconFelt>> for PublicKey<V> {
fn from(pk_poly: Polynomial<FalconFelt>) -> Self {
Self(pk_poly, PhantomData)
}
}
impl<V: FalconVariant> fmt::Debug for PublicKey<V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("PublicKey").field(&self.0).finish()
}
}
impl<V: FalconVariant> Serializable for &PublicKey<V> {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let mut buf = [0_u8; PK_LEN];
buf[0] = LOG_N;
let mut acc = 0_u32;
let mut acc_len: u32 = 0;
let mut input_pos = 1;
for c in self.0.coefficients.iter() {
let c = c.value();
acc = (acc << FALCON_ENCODING_BITS) | c as u32;
acc_len += FALCON_ENCODING_BITS;
while acc_len >= 8 {
acc_len -= 8;
buf[input_pos] = (acc >> acc_len) as u8;
input_pos += 1;
}
}
if acc_len > 0 {
buf[input_pos] = (acc >> (8 - acc_len)) as u8;
}
target.write(buf);
}
}
impl<V: FalconVariant> fmt::Display for PublicKey<V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
crate::utils::write_hex(f, &self.to_bytes())
}
}
impl<V: FalconVariant> Deserializable for PublicKey<V> {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let buf = source.read_array::<PK_LEN>()?;
if buf[0] != LOG_N {
return Err(DeserializationError::InvalidValue(format!(
"Failed to decode public key: expected the first byte to be {LOG_N} but was {}",
buf[0]
)));
}
let mut acc = 0_u32;
let mut acc_len = 0;
let mut output = [FalconFelt::zero(); N];
let mut output_idx = 0;
for &byte in buf.iter().skip(1) {
acc = (acc << 8) | (byte as u32);
acc_len += 8;
if acc_len >= FALCON_ENCODING_BITS {
acc_len -= FALCON_ENCODING_BITS;
let w = (acc >> acc_len) & 0x3fff;
let element = w.try_into().map_err(|err| {
DeserializationError::InvalidValue(format!(
"Failed to decode public key: {err}"
))
})?;
output[output_idx] = element;
output_idx += 1;
}
}
if (acc & ((1u32 << acc_len) - 1)) == 0 {
Ok(Polynomial::new(output.to_vec()).into())
} else {
Err(DeserializationError::InvalidValue(
"Failed to decode public key: input not fully consumed".to_string(),
))
}
}
}