use alloc::vec::Vec;
use super::{MODULUS, N, Nonce, Polynomial, falcon512_common::FalconFelt};
use crate::{Felt, Word, ZERO, hash::poseidon2::Poseidon2};
pub fn hash_to_point_poseidon2(message: Word, nonce: &Nonce) -> Polynomial<FalconFelt> {
let mut state = [ZERO; Poseidon2::STATE_WIDTH];
let nonce_elements = nonce.to_elements();
for (&n, s) in nonce_elements.iter().zip(state[Poseidon2::RATE_RANGE].iter_mut()) {
*s = n;
}
Poseidon2::apply_permutation(&mut state);
for (&m, s) in message.iter().zip(state[Poseidon2::RATE_RANGE].iter_mut()) {
*s = m;
}
let mut coefficients: Vec<FalconFelt> = Vec::with_capacity(N);
for _ in 0..64 {
Poseidon2::apply_permutation(&mut state);
state[Poseidon2::RATE_RANGE]
.iter()
.for_each(|value| coefficients.push(felt_to_falcon_felt(*value)));
}
Polynomial::new(coefficients)
}
fn felt_to_falcon_felt(value: Felt) -> FalconFelt {
FalconFelt::new((value.as_canonical_u64() % MODULUS as u64) as i16)
}