Adding expand_message_xmd and RFC compliance with VOPRF and H2C (#80)

This commit is contained in:
Kevin Lewi
2020-11-12 10:00:09 -08:00
committed by GitHub
parent 09f7cfdf78
commit f165310c96
8 changed files with 329 additions and 95 deletions
+32 -20
View File
@@ -80,33 +80,45 @@ impl<T: CipherSuite> From<&LoginThirdMessage<T>> for ProtocolMessageType {
}
}
pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Vec<u8> {
let mut output: Vec<u8> = Vec::new();
output
.extend_from_slice(&input.len().to_be_bytes()[std::mem::size_of::<usize>() - max_bytes..]);
output.extend_from_slice(&input[..]);
// Corresponds to the I2OSP() function from RFC8017
pub(crate) fn i2osp(input: usize, length: usize) -> Vec<u8> {
if length <= std::mem::size_of::<usize>() {
return (&input.to_be_bytes()[std::mem::size_of::<usize>() - length..]).to_vec();
}
let mut output = vec![0u8; length];
output.splice(
length - std::mem::size_of::<usize>()..length,
input.to_be_bytes().iter().cloned(),
);
output
}
// Corresponds to the OS2IP() function from RFC8017
pub(crate) fn os2ip(input: &[u8]) -> Result<usize, PakeError> {
if input.len() > std::mem::size_of::<usize>() {
// TODO:: check RFC compliance in refusing this
return Err(PakeError::SerializationError);
}
let mut output_array = [0u8; std::mem::size_of::<usize>()];
output_array[std::mem::size_of::<usize>() - input.len()..].copy_from_slice(input);
Ok(usize::from_be_bytes(output_array))
}
// Computes I2OSP(len(input), max_bytes) || input
pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Vec<u8> {
[&i2osp(input.len(), max_bytes), &input[..]].concat()
}
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
// (input, remainder)
pub(crate) fn tokenize(input: Vec<u8>, size_bytes: usize) -> Result<(Vec<u8>, Vec<u8>), PakeError> {
if size_bytes > 8 || input.len() < size_bytes {
if size_bytes > std::mem::size_of::<usize>() || input.len() < size_bytes {
return Err(PakeError::SerializationError);
}
let mut size_array = [0u8; 8];
for i in 0..size_bytes {
size_array[8 - size_bytes + i] = input[i];
}
let big_size = u64::from_be_bytes(size_array);
// TODO:: check RFC compliance in refusing this
if big_size >= u32::MAX as u64 {
return Err(PakeError::SerializationError);
}
let size = big_size as usize;
let size = os2ip(&input[..size_bytes])?;
if size_bytes + size > input.len() {
return Err(PakeError::SerializationError);
}
+7 -2
View File
@@ -13,7 +13,7 @@ use crate::{
},
keypair::{KeyPair, X25519KeyPair},
opaque::*,
serialization::{serialize, ProtocolMessageType},
serialization::{i2osp, os2ip, serialize, ProtocolMessageType},
};
use curve25519_dalek::ristretto::RistrettoPoint;
@@ -240,7 +240,7 @@ fn login_second_message_roundtrip() {
let ke2m: Vec<u8> = [&server_nonce[..], &server_e_kp.public(), &mac[..]].concat();
let total_length_without_ke2m: usize = pt_bytes.len() + envelope.to_bytes().len() + 2;
let total_length_without_ke2m = pt_bytes.len() + envelope.to_bytes().len() + 2;
let mut input = Vec::new();
input.extend_from_slice(&[ProtocolMessageType::CredentialResponse as u8 + 1]);
@@ -312,6 +312,11 @@ fn ke1_message_roundtrip() {
proptest! {
#[test]
fn test_i2osp_os2ip(bytes in vec(any::<u8>(), 0..std::mem::size_of::<usize>())) {
assert_eq!(i2osp(os2ip(&bytes)?, bytes.len()), bytes);
}
#[test]
fn test_nocrash_register_first_message(bytes in vec(any::<u8>(), 0..200)) {
RegisterFirstMessage::<RistrettoPoint>::try_from(&bytes[..]).map_or(true, |_| true);