use alloc::vec;
use alloc::vec::Vec;
use pakery_core::crypto::{CpaceGroup, Hash};
use pakery_core::encoding::{lv_cat, prepend_len};
use crate::ciphersuite::CpaceCiphersuite;
pub fn generator_string<C: CpaceCiphersuite>(password: &[u8], ci: &[u8], sid: &[u8]) -> Vec<u8> {
let s_in_bytes = C::HASH_BLOCK_SIZE;
let prepend_len_dsi_len = prepend_len(C::DSI).len();
let prepend_len_prs_len = prepend_len(password).len();
let len_zpad = s_in_bytes
.saturating_sub(1)
.saturating_sub(prepend_len_prs_len)
.saturating_sub(prepend_len_dsi_len);
let zpad = vec![0u8; len_zpad];
lv_cat(&[C::DSI, password, &zpad, ci, sid])
}
pub fn calculate_generator<C: CpaceCiphersuite>(
password: &[u8],
ci: &[u8],
sid: &[u8],
) -> Result<C::Group, pakery_core::PakeError> {
const { assert!(<C::Hash as pakery_core::crypto::Hash>::OUTPUT_SIZE >= 2 * C::FIELD_SIZE_BYTES) };
let gen_str = generator_string::<C>(password, ci, sid);
let hash_output = C::Hash::digest(&gen_str);
let g = C::Group::from_uniform_bytes(&hash_output)?;
if g.is_identity() {
return Err(pakery_core::PakeError::IdentityPoint);
}
Ok(g)
}