Start integrating the derivable SizedBytes

- just derive it on Key and KeyPair for now
This commit is contained in:
François Garillot
2020-11-03 16:45:37 -05:00
parent 3954cd23b8
commit 230b1bcef6
10 changed files with 84 additions and 100 deletions
Generated
+22
View File
@@ -335,6 +335,26 @@ dependencies = [
"version_check",
]
[[package]]
name = "generic-bytes"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6638d839bbd1cea640d8c5348dd82e0d545dbd364f3c2a251646eaf2ef0773b"
dependencies = [
"generic-array",
]
[[package]]
name = "generic-bytes-derive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4257fe99e64e321c197164da8ae22f7a3c074a5b2519072866e2d38bc1ca59e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "getrandom"
version = "0.1.14"
@@ -518,6 +538,8 @@ dependencies = [
"displaydoc",
"fiat-crypto",
"generic-array",
"generic-bytes",
"generic-bytes-derive",
"hex",
"hkdf",
"hmac 0.9.0",
+2
View File
@@ -22,6 +22,8 @@ digest = "0.9.0"
displaydoc = "0.1.7"
fiat-crypto = { version = "0.1.5"}
generic-array = "0.14.4"
generic-bytes = { version = "0.1.0" }
generic-bytes-derive = { version = "0.1.0" }
hkdf = "0.9.0"
hmac = "0.9.0"
rand_core = "0.5.1"
+20
View File
@@ -10,6 +10,8 @@ use thiserror::Error;
/// Represents an error in the manipulation of internal cryptographic data
#[derive(Debug, Display, Error)]
pub enum InternalPakeError {
/// Deserializing from a byte sequence failed
InvalidByteSequence,
/// Invalid length for {name}: expected {len}, but is actually {actual_len}.
SizeError {
/// name
@@ -116,6 +118,24 @@ impl From<::std::convert::Infallible> for ProtocolError {
}
}
impl From<generic_bytes::TryFromSizedBytesError> for InternalPakeError {
fn from(_: generic_bytes::TryFromSizedBytesError) -> Self {
InternalPakeError::InvalidByteSequence
}
}
impl From<generic_bytes::TryFromSizedBytesError> for PakeError {
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
PakeError::CryptoError(e.into())
}
}
impl From<generic_bytes::TryFromSizedBytesError> for ProtocolError {
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
PakeError::CryptoError(e.into()).into()
}
}
pub(crate) mod utils {
use super::*;
+1
View File
@@ -17,6 +17,7 @@ use generic_array::{
typenum::{U32, U64},
ArrayLength, GenericArray,
};
use rand_core::{CryptoRng, RngCore};
use std::ops::Mul;
use zeroize::Zeroize;
+2 -1
View File
@@ -8,7 +8,7 @@ use crate::{
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
hash::Hash,
key_exchange::traits::{KeyExchange, ToBytes},
keypair::{KeyPair, SizedBytes},
keypair::{KeyPair, SizedBytesExt},
serialization::serialize,
};
use digest::{Digest, FixedOutput};
@@ -16,6 +16,7 @@ use generic_array::{
typenum::{Unsigned, U32},
ArrayLength, GenericArray,
};
use generic_bytes::SizedBytes;
use hkdf::Hkdf;
use hmac::{Hmac, Mac, NewMac};
use rand_core::{CryptoRng, RngCore};
+19 -84
View File
@@ -5,12 +5,10 @@
//! Contains the keypair types that must be supplied for the OPAQUE API
use crate::errors::{utils::check_slice_size, InternalPakeError};
use generic_array::{
sequence::Concat,
typenum::{Sum, Unsigned, U32},
ArrayLength, GenericArray,
};
use crate::errors::InternalPakeError;
use generic_array::{typenum::U32, GenericArray};
use generic_bytes::{SizedBytes, TryFromSizedBytesError};
use generic_bytes_derive::{SizedBytes, TryFromForSizedBytes};
#[cfg(test)]
use proptest::prelude::*;
#[cfg(test)]
@@ -20,25 +18,18 @@ use std::convert::TryInto;
use std::fmt::Debug;
use x25519_dalek::{PublicKey, StaticSecret};
use std::convert::TryFrom;
use std::ops::Deref;
use std::ops::{Add, Deref};
/// A trait for sized key material that can be represented within a fixed byte
/// array size, used to represent our DH key types
pub trait SizedBytes: Sized + PartialEq {
/// The typed representation of the byte length
type Len: ArrayLength<u8>;
/// Converts this sized key material to a `GenericArray` of the same
/// size. One can convert this to a `&[u8]` with `GenericArray::as_slice()`
/// but the size information is then lost from the type.
fn to_arr(&self) -> GenericArray<u8, Self::Len>;
/// How to parse such sized material from a byte slice.
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError>;
// Pub(crate) convenience extension trait of SizedBytes for our purposes
pub(crate) trait SizedBytesExt: SizedBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self, TryFromSizedBytesError> {
<Self as SizedBytes>::from_arr(GenericArray::from_slice(bytes))
}
}
// blanket implementation
impl<T> SizedBytesExt for T where T: SizedBytes {}
/// A Keypair trait with public-private verification
pub trait KeyPair: Sized {
/// The single key representation must have a specific byte size itself
@@ -92,62 +83,9 @@ trait KeyPairExt: KeyPair + Debug {
#[cfg(test)]
impl<KP> KeyPairExt for KP where KP: KeyPair + Debug {}
/// This assumes you have defined a SizedBytes instance for a `T`, and defines:
/// - an `impl TryFrom<&[u8b], Error = InternalPakeError>` for a non-generic `T`
/// - an `fn to_bytes(&self) -> Vec<u8>` in an `impl T` block
///
/// Because SizedBytes has a strong notion of size, and TryFrom/to_bytes does
/// not, it's better to use this macro than the one above, where possible.
macro_rules! try_from_and_to_bytes_using_sized_bytes {
($sized_type: ident) => {
impl TryFrom<&[u8]> for $sized_type {
type Error = InternalPakeError;
fn try_from(bytes: &[u8]) -> Result<Self, InternalPakeError> {
<$sized_type as SizedBytes>::from_bytes(bytes)
}
}
#[allow(dead_code)]
impl $sized_type {
fn to_bytes(&self) -> Vec<u8> {
self.to_arr().to_vec()
}
}
};
}
/// This is a blanket implementation of SizedBytes for any instance of KeyPair
/// with any length of keys. This encodes that we serialize the public key
/// first, followed by the private key in binary formats (and expect it in this
/// order upon decoding).
impl<T, KP> SizedBytes for KP
where
T: SizedBytes + Clone,
KP: KeyPair<Repr = T> + PartialEq,
T::Len: Add<T::Len>,
Sum<T::Len, T::Len>: ArrayLength<u8>,
{
type Len = Sum<T::Len, T::Len>;
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
let private = self.private().to_arr();
let public = self.public().to_arr();
public.concat(private)
}
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
let checked_bytes =
check_slice_size(key_bytes, <Self::Len as Unsigned>::to_usize(), "key_bytes")?;
let single_key_len = <<KP::Repr as SizedBytes>::Len as Unsigned>::to_usize();
let public = <T as SizedBytes>::from_bytes(&checked_bytes[..single_key_len])?;
let private = <T as SizedBytes>::from_bytes(&checked_bytes[single_key_len..])?;
KP::new(public, private)
}
}
/// A minimalist key type built around [u8;32]
#[derive(Debug, PartialEq, Eq, Clone)]
#[derive(Debug, PartialEq, Eq, Clone, TryFromForSizedBytes)]
#[ErrorType = "::generic_bytes::TryFromSizedBytesError"]
#[repr(transparent)]
pub struct Key(Vec<u8>);
@@ -166,17 +104,14 @@ impl SizedBytes for Key {
GenericArray::clone_from_slice(&self.0[..])
}
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
let checked_bytes =
check_slice_size(key_bytes, <Self::Len as Unsigned>::to_usize(), "key_bytes")?;
Ok(Key(checked_bytes.to_vec()))
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
Ok(Key(key_bytes.to_vec()))
}
}
try_from_and_to_bytes_using_sized_bytes!(Key);
/// A representation of an X25519 keypair according to RFC7748
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, SizedBytes, TryFromForSizedBytes)]
#[ErrorType = "::generic_bytes::TryFromSizedBytesError"]
pub struct X25519KeyPair {
pk: Key,
sk: Key,
+9 -9
View File
@@ -40,7 +40,7 @@
//! ## Setup
//! To setup the protocol, the server begins by generating a static keypair:
//! ```
//! # use opaque_ke::keypair::{KeyPair, X25519KeyPair, SizedBytes};
//! # use opaque_ke::keypair::{KeyPair, X25519KeyPair};
//! # use opaque_ke::errors::ProtocolError;
//! # use opaque_ke::ciphersuite::CipherSuite;
//! # struct Default;
@@ -72,7 +72,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::ServerRegistration,
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -102,7 +102,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::ClientRegistration,
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -135,7 +135,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -169,7 +169,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -211,7 +211,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -241,7 +241,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -285,7 +285,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -340,7 +340,7 @@
//! # use opaque_ke::{
//! # errors::ProtocolError,
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
//! # keypair::{KeyPair, X25519KeyPair},
//! # slow_hash::NoOpHash,
//! # };
//! # use opaque_ke::ciphersuite::CipherSuite;
+5 -4
View File
@@ -15,7 +15,7 @@ use crate::{
group::Group,
hash::Hash,
key_exchange::traits::{KeyExchange, ToBytes},
keypair::{KeyPair, SizedBytes},
keypair::{KeyPair, SizedBytesExt},
oprf,
serialization::{
serialize, tokenize, u8_to_credential_type, CredentialType, ProtocolMessageType,
@@ -23,6 +23,7 @@ use crate::{
slow_hash::SlowHash,
};
use generic_array::{typenum::Unsigned, GenericArray};
use generic_bytes::SizedBytes;
use rand_core::{CryptoRng, RngCore};
use std::collections::HashMap;
use std::{convert::TryFrom, marker::PhantomData};
@@ -640,7 +641,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
/// # Example
///
/// ```
/// use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{X25519KeyPair, SizedBytes}};
/// use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::X25519KeyPair};
/// # use opaque_ke::errors::ProtocolError;
/// # use opaque_ke::keypair::KeyPair;
/// use rand_core::{OsRng, RngCore};
@@ -822,7 +823,7 @@ where
/// # Example
///
/// ```
/// use opaque_ke::{opaque::*, keypair::{X25519KeyPair, SizedBytes}};
/// use opaque_ke::{opaque::*, keypair::X25519KeyPair};
/// # use opaque_ke::errors::ProtocolError;
/// use rand_core::{OsRng, RngCore};
/// use opaque_ke::ciphersuite::CipherSuite;
@@ -898,7 +899,7 @@ where
/// # Example
///
/// ```
/// use opaque_ke::{opaque::*, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
/// use opaque_ke::{opaque::*, keypair::{KeyPair, X25519KeyPair}};
/// # use opaque_ke::errors::ProtocolError;
/// use rand_core::{OsRng, RngCore};
/// use opaque_ke::ciphersuite::CipherSuite;
+2 -1
View File
@@ -11,12 +11,13 @@ use crate::{
traits::{KeyExchange, ToBytes},
tripledh::{TripleDH, NONCE_LEN},
},
keypair::{KeyPair, SizedBytes, X25519KeyPair},
keypair::{KeyPair, X25519KeyPair},
opaque::*,
serialization::{serialize, ProtocolMessageType},
};
use curve25519_dalek::ristretto::RistrettoPoint;
use generic_bytes::SizedBytes;
use proptest::{collection::vec, prelude::*};
use rand_core::{OsRng, RngCore};
+2 -1
View File
@@ -8,13 +8,14 @@ use crate::{
errors::*,
group::Group,
key_exchange::tripledh::{TripleDH, NONCE_LEN},
keypair::{Key, KeyPair, SizedBytes, X25519KeyPair},
keypair::{Key, KeyPair, X25519KeyPair},
opaque::*,
slow_hash::NoOpHash,
tests::mock_rng::CycleRng,
};
use curve25519_dalek::edwards::EdwardsPoint;
use generic_array::GenericArray;
use generic_bytes::SizedBytes;
use rand_core::{OsRng, RngCore};
use serde_json::Value;
use std::convert::TryFrom;