in src/serialization/tests.rs [376:461]
fn credential_response_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), 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,
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
<OprfGroup<CS> as Group>::ElemLen: Add<NonceLen>,
Sum<<OprfGroup<CS> as Group>::ElemLen, NonceLen>:
ArrayLength<u8> + Add<MaskedResponseLen<CS>>,
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
// 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>,
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
CredentialResponseLen<CS>: ArrayLength<u8>,
{
let pt = random_point::<CS>();
let pt_bytes = CS::KeGroup::serialize_pk(&pt);
let mut rng = OsRng;
let mut masking_nonce = [0u8; 32];
rng.fill_bytes(&mut masking_nonce);
let mut masked_response =
vec![0u8; <OprfGroup<CS> as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
rng.fill_bytes(&mut masked_response);
let server_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
let mut mac = Output::<OprfHash<CS>>::default();
rng.fill_bytes(&mut mac);
let mut server_nonce = [0u8; NonceLen::USIZE];
rng.fill_bytes(&mut server_nonce);
let ke2m: Vec<u8> = [
server_nonce.as_ref(),
server_e_kp.public().to_bytes().as_ref(),
&mac,
]
.concat();
let mut input = Vec::new();
input.extend_from_slice(&pt_bytes);
input.extend_from_slice(&masking_nonce);
input.extend_from_slice(&masked_response);
input.extend_from_slice(&ke2m);
let l2 = CredentialResponse::<CS>::deserialize(&input)?;
let l2_bytes = l2.serialize();
assert_eq!(input, *l2_bytes);
// Assert that identity group element is rejected
let identity = OprfGroup::<CS>::identity_elem();
let identity_bytes = OprfGroup::<CS>::serialize_elem(identity).to_vec();
assert!(matches!(
CredentialResponse::<CS>::deserialize(
&[
identity_bytes,
masking_nonce.to_vec(),
masked_response,
ke2m.to_vec()
]
.concat()
),
Err(ProtocolError::LibraryError(InternalError::OprfError(
voprf::Error::Deserialization,
)))
));
Ok(())
}
#[cfg(feature = "ristretto255")]
inner::<Ristretto255>()?;
inner::<P256>()?;
Ok(())
}