in src/opaque.rs [1249:1283]
fn unmask_response<CS: CipherSuite>(
masking_key: &[u8],
masking_nonce: &[u8],
masked_response: &MaskedResponse<CS>,
) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError>
where
<OprfHash<CS> as OutputSizeUser>::OutputSize:
IsLess<U256> + IsLessOrEqual<<OprfHash<CS> as BlockSizeUser>::BlockSize>,
OprfHash<CS>: Hash,
<OprfHash<CS> as CoreProxy>::Core: ProxyHash,
<<OprfHash<CS> as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<OprfHash<CS> as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// MaskedResponse: (Nonce + Hash) + KePk
NonceLen: Add<OutputSize<OprfHash<CS>>>,
Sum<NonceLen, OutputSize<OprfHash<CS>>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
MaskedResponseLen<CS>: ArrayLength<u8>,
{
let mut xor_pad = GenericArray::<_, MaskedResponseLen<CS>>::default();
Hkdf::<OprfHash<CS>>::from_prk(masking_key)
.map_err(|_| InternalError::HkdfError)?
.expand_multi_info(&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD], &mut xor_pad)
.map_err(|_| InternalError::HkdfError)?;
for (x1, x2) in xor_pad.iter_mut().zip(masked_response.iter().flatten()) {
*x1 ^= x2
}
let key_len = <CS::KeGroup as KeGroup>::PkLen::USIZE;
let server_s_pk = PublicKey::deserialize(&xor_pad[..key_len])
.map_err(|_| ProtocolError::SerializationError)?;
let envelope = Envelope::deserialize(&xor_pad[key_len..])?;
Ok((server_s_pk, envelope))
}