use super::super::{ExecutionError, Felt, Word};
use alloc::vec::Vec;
#[cfg(feature = "std")]
pub fn falcon_sign(sk: &[Felt], msg: Word) -> Result<Vec<Felt>, ExecutionError> {
use vm_core::{
crypto::dsa::rpo_falcon512::{Polynomial, SecretKey},
utils::Deserializable,
};
let mut sk_bytes = Vec::with_capacity(sk.len());
for element in sk {
let value = element.as_int();
if value > u8::MAX as u64 {
return Err(ExecutionError::MalformedSignatureKey("RPO Falcon512"));
}
sk_bytes.push(value as u8);
}
let sk = SecretKey::read_from_bytes(&sk_bytes)
.map_err(|_| ExecutionError::MalformedSignatureKey("RPO Falcon512"))?;
let sig = sk.sign(msg);
let nonce = sig.nonce();
let s2 = sig.sig_poly();
let h = sk.compute_pub_key_poly().0;
let pi = Polynomial::mul_modulo_p(&h, s2);
let mut result: Vec<Felt> = nonce.to_elements().to_vec();
result.extend(h.coefficients.iter().map(|a| Felt::from(a.value() as u32)));
result.extend(s2.coefficients.iter().map(|a| Felt::from(a.value() as u32)));
result.extend(pi.iter().map(|a| Felt::new(*a)));
result.reverse();
Ok(result)
}
#[cfg(not(feature = "std"))]
pub fn falcon_sign(sk: &[Felt], msg: Word) -> Result<Vec<Felt>, ExecutionError> {
Err(ExecutionError::FailedSignatureGeneration(
"RPO Falcon512 signature generation is not available in no_std context",
))
}