Voprf update (#255)

* Update to latest voprf

* Upgrade to Rust edition 2021

* Fix Clippy

* Remove all allocations

* Remove unnecessary `allow(type_alias_bounds)`

* Make all serialization infallible

* Remove self-dependency

* Update rustyline
This commit is contained in:
daxpedda
2022-01-05 15:10:57 -08:00
committed by GitHub
parent 82e4436d39
commit 36f0a55518
26 changed files with 1399 additions and 876 deletions
+10 -43
View File
@@ -20,23 +20,19 @@ pub(crate) fn i2osp<L: ArrayLength<u8>>(
) -> Result<GenericArray<u8, L>, ProtocolError> {
const SIZEOF_USIZE: usize = core::mem::size_of::<usize>();
// Check if input >= 256^length
// Make sure input fits in output.
if (SIZEOF_USIZE as u32 - input.leading_zeros() / 8) > L::U32 {
return Err(ProtocolError::SerializationError);
}
if L::USIZE <= SIZEOF_USIZE {
return Ok(GenericArray::clone_from_slice(
&input.to_be_bytes()[SIZEOF_USIZE - L::USIZE..],
));
}
let mut output = GenericArray::default();
output[L::USIZE - SIZEOF_USIZE..L::USIZE].copy_from_slice(&input.to_be_bytes());
output[L::USIZE.saturating_sub(SIZEOF_USIZE)..]
.copy_from_slice(&input.to_be_bytes()[SIZEOF_USIZE.saturating_sub(L::USIZE)..]);
Ok(output)
}
// Corresponds to the OS2IP() function from RFC8017
#[cfg(test)]
pub(crate) fn os2ip(input: &[u8]) -> Result<usize, ProtocolError> {
if input.len() > core::mem::size_of::<usize>() {
return Err(ProtocolError::SerializationError);
@@ -96,17 +92,17 @@ impl<'a, L1: ArrayLength<u8>, L2: ArrayLength<u8>, L3: ArrayLength<u8>> Serializ
pub(crate) fn iter(&self) -> impl Iterator<Item = &[u8]> {
// Some magic to make it output the same type in all branches.
Some(self.octet.as_slice())
[self.octet.as_slice()]
.into_iter()
.chain(match &self.input {
Input::Owned(bytes) => Some(bytes.as_slice()),
Input::Borrowed(bytes) => Some(*bytes),
Input::Label(_) => None,
Input::Owned(bytes) => [bytes.as_slice()],
Input::Borrowed(bytes) => [*bytes],
Input::Label((iter, _)) => [iter[0]],
})
.chain(if let Input::Label((iter, _)) = &self.input {
Some(iter[0]).into_iter().chain(Some(iter[1]).into_iter())
Some(iter[1])
} else {
None.into_iter().chain(None)
None
})
}
}
@@ -132,24 +128,6 @@ impl<'a, L1: ArrayLength<u8>, L2: ArrayLength<u8>> Serialize<'a, L1, L2, U2> {
}
}
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
// (input, remainder)
pub(crate) fn tokenize(input: &[u8], size_bytes: usize) -> Result<(&[u8], &[u8]), ProtocolError> {
if size_bytes > core::mem::size_of::<usize>() || input.len() < size_bytes {
return Err(ProtocolError::SerializationError);
}
let size = os2ip(&input[..size_bytes])?;
if size_bytes + size > input.len() {
return Err(ProtocolError::SerializationError);
}
Ok((
&input[size_bytes..size_bytes + size],
&input[size_bytes + size..],
))
}
pub(crate) trait UpdateExt {
fn chain_iter<'a>(self, iter: impl Iterator<Item = &'a [u8]>) -> Self;
}
@@ -178,17 +156,6 @@ impl<T: Mac> MacExt for T {
}
}
/// The purpose of this macro is to simplify [`concat`](alloc::slice::Concat::concat)ing
/// slices into an [`Iterator`] to avoid allocation
macro_rules! chain {
(
$item1:expr,
$($item2:expr),+$(,)?
) => {
$item1$(.chain($item2))+
};
}
#[cfg(test)]
mod tests;
+120 -63
View File
@@ -9,9 +9,10 @@ use crate::{
ciphersuite::CipherSuite,
envelope::{Envelope, EnvelopeLen, InnerEnvelopeMode},
errors::*,
hash::{OutputSize, ProxyHash},
key_exchange::{
group::KeGroup,
traits::{Ke1MessageLen, Ke2MessageLen},
traits::{Ke1MessageLen, Ke1StateLen, Ke2MessageLen},
},
key_exchange::{
traits::{FromBytes, KeyExchange, ToBytes},
@@ -19,26 +20,23 @@ use crate::{
},
keypair::KeyPair,
messages::CredentialResponseWithoutKeLen,
opaque::MaskedResponseLen,
serialization::{i2osp, os2ip, Serialize},
opaque::{ClientLoginLen, ClientRegistrationLen, MaskedResponseLen},
serialization::{i2osp, os2ip},
*,
};
#[cfg(test)]
use alloc::vec;
#[cfg(test)]
use alloc::vec::Vec;
use core::ops::Add;
use std::vec;
use std::vec::Vec;
use digest::FixedOutput;
use digest::core_api::{BlockSizeUser, CoreProxy};
use digest::Output;
use generic_array::{
typenum::{Sum, Unsigned, U2},
ArrayLength, GenericArray,
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256},
ArrayLength,
};
use proptest::{collection::vec, prelude::*};
use rand::{rngs::OsRng, RngCore};
use voprf::group::Group;
use sha2::Digest;
use voprf::Group;
#[cfg(feature = "ristretto255")]
struct Ristretto255;
@@ -62,7 +60,12 @@ impl CipherSuite for P256 {
type SlowHash = crate::slow_hash::NoOpHash;
}
fn random_point<CS: CipherSuite>() -> CS::KeGroup {
fn random_point<CS: CipherSuite>() -> CS::KeGroup
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let mut rng = OsRng;
let sk = CS::KeGroup::random_sk(&mut rng);
CS::KeGroup::public_key(&sk)
@@ -70,24 +73,32 @@ fn random_point<CS: CipherSuite>() -> CS::KeGroup {
#[test]
fn client_registration_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// ClientRegistration: KgSk + KgPk
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
ClientRegistrationLen<CS>: ArrayLength<u8>,
{
let pw = b"hunter2";
let mut rng = OsRng;
let blind_result =
&voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw.to_vec(), &mut rng)?;
&voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw, &mut rng)?;
let bytes: Vec<u8> = chain!(
Serialize::<U2>::from(&blind_result.state.serialize())?.iter(),
Serialize::<U2>::from(&blind_result.message.serialize())?.iter(),
)
.flatten()
.cloned()
.collect();
let bytes: Vec<u8> = blind_result
.state
.serialize()
.iter()
.chain(blind_result.message.serialize().iter())
.cloned()
.collect();
let reg = ClientRegistration::<CS>::deserialize(&bytes)?;
let reg_bytes = reg.serialize()?;
assert_eq!(reg_bytes, bytes);
let reg_bytes = reg.serialize();
assert_eq!(*reg_bytes, bytes);
Ok(())
}
@@ -103,12 +114,15 @@ fn client_registration_roundtrip() -> Result<(), ProtocolError> {
fn server_registration_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// Envelope: Nonce + Hash
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
NonceLen: Add<OutputSize<CS::Hash>>,
EnvelopeLen<CS>: ArrayLength<u8>,
// RegistrationUpload: (KePk + Hash) + Envelope
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
RegistrationUploadLen<CS>: ArrayLength<u8>,
// ServerRegistration = RegistrationUpload
@@ -116,15 +130,14 @@ fn server_registration_roundtrip() -> Result<(), ProtocolError> {
// If we don't have envelope and client_pk, the server registration just
// contains the prf key
let mut rng = OsRng;
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut masking_key = Output::<CS::Hash>::default();
rng.fill_bytes(&mut masking_key);
// Construct a mock envelope
let mut mock_envelope_bytes = Vec::new();
mock_envelope_bytes.extend_from_slice(&[0; NonceLen::USIZE]); // empty nonce
// mock_envelope_bytes.extend_from_slice(&ciphertext); // ciphertext which is an encrypted private key
mock_envelope_bytes
.extend_from_slice(&GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default()); // length-MAC_SIZE hmac
mock_envelope_bytes.extend_from_slice(&Output::<CS::Hash>::default()); // length-MAC_SIZE hmac
let mock_client_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
// serialization order: oprf_key, public key, envelope
@@ -148,7 +161,12 @@ fn server_registration_roundtrip() -> Result<(), ProtocolError> {
#[test]
fn registration_request_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let pt = random_point::<CS>();
let pt_bytes = pt.to_arr().to_vec();
@@ -166,7 +184,7 @@ fn registration_request_roundtrip() -> Result<(), ProtocolError> {
assert!(matches!(
RegistrationRequest::<CS>::deserialize(&identity_bytes),
Err(ProtocolError::LibraryError(InternalError::OprfError(
voprf::errors::InternalError::PointError,
voprf::Error::PointError,
)))
));
@@ -185,6 +203,9 @@ fn registration_request_roundtrip() -> Result<(), ProtocolError> {
fn registration_response_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// RegistrationResponse: KgPk + KePk
<CS::OprfGroup as Group>::ElemLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
RegistrationResponseLen<CS>: ArrayLength<u8>,
@@ -212,7 +233,7 @@ fn registration_response_roundtrip() -> Result<(), ProtocolError> {
&[identity_bytes, pubkey_bytes.to_vec()].concat()
),
Err(ProtocolError::LibraryError(InternalError::OprfError(
voprf::errors::InternalError::PointError,
voprf::Error::PointError,
)))
));
@@ -231,12 +252,15 @@ fn registration_response_roundtrip() -> Result<(), ProtocolError> {
fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// Envelope: Nonce + Hash
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
NonceLen: Add<OutputSize<CS::Hash>>,
EnvelopeLen<CS>: ArrayLength<u8>,
// RegistrationUpload: (KePk + Hash) + Envelope
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
RegistrationUploadLen<CS>: ArrayLength<u8>,
{
@@ -249,7 +273,7 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
let mut nonce = [0u8; NonceLen::USIZE];
rng.fill_bytes(&mut nonce);
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut masking_key = Output::<CS::Hash>::default();
rng.fill_bytes(&mut masking_key);
let randomized_pwd_hasher = hkdf::Hkdf::new(None, &key);
@@ -257,7 +281,7 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
let (envelope, _, _) = Envelope::<CS>::seal_raw(
randomized_pwd_hasher,
nonce.into(),
Some(pubkey_bytes.as_slice()).into_iter(),
[pubkey_bytes.as_slice()].into_iter(),
InnerEnvelopeMode::Internal,
)
.unwrap();
@@ -287,6 +311,9 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
fn credential_request_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// CredentialRequest: KgPk + Ke1Message
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
CredentialRequestLen<CS>: ArrayLength<u8>,
@@ -316,7 +343,7 @@ fn credential_request_roundtrip() -> Result<(), ProtocolError> {
assert!(matches!(
CredentialRequest::<CS>::deserialize(&[identity_bytes, ke1m.to_vec()].concat()),
Err(ProtocolError::LibraryError(InternalError::OprfError(
voprf::errors::InternalError::PointError,
voprf::Error::PointError,
)))
));
@@ -335,15 +362,17 @@ fn credential_request_roundtrip() -> Result<(), ProtocolError> {
fn credential_response_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
Sum<<CS::OprfGroup as Group>::ElemLen, NonceLen>:
ArrayLength<u8> + Add<MaskedResponseLen<CS>>,
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
// MaskedResponse: (Nonce + Hash) + KePk
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
NonceLen: Add<OutputSize<CS::Hash>>,
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
MaskedResponseLen<CS>: ArrayLength<u8>,
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
@@ -362,7 +391,7 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
rng.fill_bytes(&mut masked_response);
let server_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut mac = Output::<CS::Hash>::default();
rng.fill_bytes(&mut mac);
let mut server_nonce = [0u8; NonceLen::USIZE];
rng.fill_bytes(&mut server_nonce);
@@ -394,7 +423,7 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
.concat()
),
Err(ProtocolError::LibraryError(InternalError::OprfError(
voprf::errors::InternalError::PointError,
voprf::Error::PointError,
)))
));
@@ -411,9 +440,14 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
#[test]
fn credential_finalization_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let mut rng = OsRng;
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut mac = Output::<CS::Hash>::default();
rng.fill_bytes(&mut mac);
let input = mac;
@@ -437,9 +471,17 @@ fn credential_finalization_roundtrip() -> Result<(), ProtocolError> {
fn client_login_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
// CredentialRequest: KgPk + Ke1Message
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
CredentialRequestLen<CS>: ArrayLength<u8>,
// ClientLogin: KgSk + CredentialRequest + Ke1State
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
ArrayLength<u8> + Add<Ke1StateLen<CS>>,
ClientLoginLen<CS>: ArrayLength<u8>,
{
let pw = b"hunter2";
let mut rng = OsRng;
@@ -455,7 +497,7 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
.concat();
let blind_result =
voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw.to_vec(), &mut rng)?;
voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw, &mut rng)?;
let credential_request = CredentialRequest::<CS> {
blinded_element: blind_result.message,
@@ -465,17 +507,17 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
)?,
};
let bytes: Vec<u8> = chain!(
Serialize::<U2>::from(&blind_result.state.serialize())?.iter(),
Serialize::<U2>::from(&credential_request.serialize())?.iter(),
Serialize::<U2>::from(&l1_data)?.iter(),
)
.flatten()
.cloned()
.collect();
let bytes: Vec<u8> = blind_result
.state
.serialize()
.iter()
.chain(credential_request.serialize().iter())
.chain(l1_data.iter())
.cloned()
.collect();
let reg = ClientLogin::<CS>::deserialize(&bytes)?;
let reg_bytes = reg.serialize()?;
assert_eq!(reg_bytes, bytes);
let reg_bytes = reg.serialize();
assert_eq!(*reg_bytes, bytes);
Ok(())
}
@@ -489,7 +531,12 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
#[test]
fn ke1_message_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let mut rng = OsRng;
let client_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
@@ -515,11 +562,16 @@ fn ke1_message_roundtrip() -> Result<(), ProtocolError> {
#[test]
fn ke2_message_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let mut rng = OsRng;
let server_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut mac = Output::<CS::Hash>::default();
rng.fill_bytes(&mut mac);
let mut server_nonce = vec![0u8; NonceLen::USIZE];
rng.fill_bytes(&mut server_nonce);
@@ -544,9 +596,14 @@ fn ke2_message_roundtrip() -> Result<(), ProtocolError> {
#[test]
fn ke3_message_roundtrip() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
where
<CS::Hash as CoreProxy>::Core: ProxyHash,
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let mut rng = OsRng;
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
let mut mac = Output::<CS::Hash>::default();
rng.fill_bytes(&mut mac);
let ke3m: Vec<u8> = [mac].concat();