pakery_cpace/
generator.rs1use alloc::vec;
15use alloc::vec::Vec;
16use pakery_core::crypto::{CpaceGroup, Hash};
17use pakery_core::encoding::{lv_cat, prepend_len};
18
19use crate::ciphersuite::CpaceCiphersuite;
20
21pub fn generator_string<C: CpaceCiphersuite>(password: &[u8], ci: &[u8], sid: &[u8]) -> Vec<u8> {
25 let s_in_bytes = C::HASH_BLOCK_SIZE;
26 let prepend_len_dsi_len = prepend_len(C::DSI).len();
27 let prepend_len_prs_len = prepend_len(password).len();
28
29 let len_zpad = s_in_bytes
30 .saturating_sub(1)
31 .saturating_sub(prepend_len_prs_len)
32 .saturating_sub(prepend_len_dsi_len);
33
34 let zpad = vec![0u8; len_zpad];
35 lv_cat(&[C::DSI, password, &zpad, ci, sid])
36}
37
38pub fn calculate_generator<C: CpaceCiphersuite>(
45 password: &[u8],
46 ci: &[u8],
47 sid: &[u8],
48) -> Result<C::Group, pakery_core::PakeError> {
49 const { assert!(<C::Hash as pakery_core::crypto::Hash>::OUTPUT_SIZE >= 2 * C::FIELD_SIZE_BYTES) };
50 let gen_str = generator_string::<C>(password, ci, sid);
51 let hash_output = C::Hash::digest(&gen_str);
52 let g = C::Group::from_uniform_bytes(&hash_output)?;
53 if g.is_identity() {
54 return Err(pakery_core::PakeError::IdentityPoint);
55 }
56 Ok(g)
57}