Skip to content

Commit 8d29f72

Browse files
huitseekerkevinlewi
authored andcommitted
Start integrating the derivable SizedBytes
- just derive it on Key and KeyPair for now
1 parent 9c38002 commit 8d29f72

File tree

10 files changed

+84
-100
lines changed

10 files changed

+84
-100
lines changed

Cargo.lock

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ digest = "0.9.0"
2222
displaydoc = "0.1.7"
2323
fiat-crypto = { version = "0.1.5"}
2424
generic-array = "0.14.4"
25+
generic-bytes = { version = "0.1.0" }
26+
generic-bytes-derive = { version = "0.1.0" }
2527
hkdf = "0.9.0"
2628
hmac = "0.9.0"
2729
rand_core = "0.5.1"

src/errors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use thiserror::Error;
1010
/// Represents an error in the manipulation of internal cryptographic data
1111
#[derive(Debug, Display, Error)]
1212
pub enum InternalPakeError {
13+
/// Deserializing from a byte sequence failed
14+
InvalidByteSequence,
1315
/// Invalid length for {name}: expected {len}, but is actually {actual_len}.
1416
SizeError {
1517
/// name
@@ -116,6 +118,24 @@ impl From<::std::convert::Infallible> for ProtocolError {
116118
}
117119
}
118120

121+
impl From<generic_bytes::TryFromSizedBytesError> for InternalPakeError {
122+
fn from(_: generic_bytes::TryFromSizedBytesError) -> Self {
123+
InternalPakeError::InvalidByteSequence
124+
}
125+
}
126+
127+
impl From<generic_bytes::TryFromSizedBytesError> for PakeError {
128+
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
129+
PakeError::CryptoError(e.into())
130+
}
131+
}
132+
133+
impl From<generic_bytes::TryFromSizedBytesError> for ProtocolError {
134+
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
135+
PakeError::CryptoError(e.into()).into()
136+
}
137+
}
138+
119139
pub(crate) mod utils {
120140
use super::*;
121141

src/group.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use generic_array::{
1717
typenum::{U32, U64},
1818
ArrayLength, GenericArray,
1919
};
20+
2021
use rand_core::{CryptoRng, RngCore};
2122
use std::ops::Mul;
2223
use zeroize::Zeroize;

src/key_exchange/tripledh.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ use crate::{
88
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
99
hash::Hash,
1010
key_exchange::traits::{KeyExchange, ToBytes},
11-
keypair::{KeyPair, SizedBytes},
11+
keypair::{KeyPair, SizedBytesExt},
1212
serialization::serialize,
1313
};
1414
use digest::{Digest, FixedOutput};
1515
use generic_array::{
1616
typenum::{Unsigned, U32},
1717
ArrayLength, GenericArray,
1818
};
19+
use generic_bytes::SizedBytes;
1920
use hkdf::Hkdf;
2021
use hmac::{Hmac, Mac, NewMac};
2122
use rand_core::{CryptoRng, RngCore};

src/keypair.rs

Lines changed: 19 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55

66
//! Contains the keypair types that must be supplied for the OPAQUE API
77
8-
use crate::errors::{utils::check_slice_size, InternalPakeError};
9-
use generic_array::{
10-
sequence::Concat,
11-
typenum::{Sum, Unsigned, U32},
12-
ArrayLength, GenericArray,
13-
};
8+
use crate::errors::InternalPakeError;
9+
use generic_array::{typenum::U32, GenericArray};
10+
use generic_bytes::{SizedBytes, TryFromSizedBytesError};
11+
use generic_bytes_derive::{SizedBytes, TryFromForSizedBytes};
1412
#[cfg(test)]
1513
use proptest::prelude::*;
1614
#[cfg(test)]
@@ -20,25 +18,18 @@ use std::convert::TryInto;
2018
use std::fmt::Debug;
2119
use x25519_dalek::{PublicKey, StaticSecret};
2220

23-
use std::convert::TryFrom;
21+
use std::ops::Deref;
2422

25-
use std::ops::{Add, Deref};
26-
27-
/// A trait for sized key material that can be represented within a fixed byte
28-
/// array size, used to represent our DH key types
29-
pub trait SizedBytes: Sized + PartialEq {
30-
/// The typed representation of the byte length
31-
type Len: ArrayLength<u8>;
32-
33-
/// Converts this sized key material to a `GenericArray` of the same
34-
/// size. One can convert this to a `&[u8]` with `GenericArray::as_slice()`
35-
/// but the size information is then lost from the type.
36-
fn to_arr(&self) -> GenericArray<u8, Self::Len>;
37-
38-
/// How to parse such sized material from a byte slice.
39-
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError>;
23+
// Pub(crate) convenience extension trait of SizedBytes for our purposes
24+
pub(crate) trait SizedBytesExt: SizedBytes {
25+
fn from_bytes(bytes: &[u8]) -> Result<Self, TryFromSizedBytesError> {
26+
<Self as SizedBytes>::from_arr(GenericArray::from_slice(bytes))
27+
}
4028
}
4129

30+
// blanket implementation
31+
impl<T> SizedBytesExt for T where T: SizedBytes {}
32+
4233
/// A Keypair trait with public-private verification
4334
pub trait KeyPair: Sized {
4435
/// The single key representation must have a specific byte size itself
@@ -92,62 +83,9 @@ trait KeyPairExt: KeyPair + Debug {
9283
#[cfg(test)]
9384
impl<KP> KeyPairExt for KP where KP: KeyPair + Debug {}
9485

95-
/// This assumes you have defined a SizedBytes instance for a `T`, and defines:
96-
/// - an `impl TryFrom<&[u8b], Error = InternalPakeError>` for a non-generic `T`
97-
/// - an `fn to_bytes(&self) -> Vec<u8>` in an `impl T` block
98-
///
99-
/// Because SizedBytes has a strong notion of size, and TryFrom/to_bytes does
100-
/// not, it's better to use this macro than the one above, where possible.
101-
macro_rules! try_from_and_to_bytes_using_sized_bytes {
102-
($sized_type: ident) => {
103-
impl TryFrom<&[u8]> for $sized_type {
104-
type Error = InternalPakeError;
105-
106-
fn try_from(bytes: &[u8]) -> Result<Self, InternalPakeError> {
107-
<$sized_type as SizedBytes>::from_bytes(bytes)
108-
}
109-
}
110-
111-
#[allow(dead_code)]
112-
impl $sized_type {
113-
fn to_bytes(&self) -> Vec<u8> {
114-
self.to_arr().to_vec()
115-
}
116-
}
117-
};
118-
}
119-
120-
/// This is a blanket implementation of SizedBytes for any instance of KeyPair
121-
/// with any length of keys. This encodes that we serialize the public key
122-
/// first, followed by the private key in binary formats (and expect it in this
123-
/// order upon decoding).
124-
impl<T, KP> SizedBytes for KP
125-
where
126-
T: SizedBytes + Clone,
127-
KP: KeyPair<Repr = T> + PartialEq,
128-
T::Len: Add<T::Len>,
129-
Sum<T::Len, T::Len>: ArrayLength<u8>,
130-
{
131-
type Len = Sum<T::Len, T::Len>;
132-
133-
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
134-
let private = self.private().to_arr();
135-
let public = self.public().to_arr();
136-
public.concat(private)
137-
}
138-
139-
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
140-
let checked_bytes =
141-
check_slice_size(key_bytes, <Self::Len as Unsigned>::to_usize(), "key_bytes")?;
142-
let single_key_len = <<KP::Repr as SizedBytes>::Len as Unsigned>::to_usize();
143-
let public = <T as SizedBytes>::from_bytes(&checked_bytes[..single_key_len])?;
144-
let private = <T as SizedBytes>::from_bytes(&checked_bytes[single_key_len..])?;
145-
KP::new(public, private)
146-
}
147-
}
148-
14986
/// A minimalist key type built around [u8;32]
150-
#[derive(Debug, PartialEq, Eq, Clone)]
87+
#[derive(Debug, PartialEq, Eq, Clone, TryFromForSizedBytes)]
88+
#[ErrorType = "::generic_bytes::TryFromSizedBytesError"]
15189
#[repr(transparent)]
15290
pub struct Key(Vec<u8>);
15391

@@ -166,17 +104,14 @@ impl SizedBytes for Key {
166104
GenericArray::clone_from_slice(&self.0[..])
167105
}
168106

169-
fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
170-
let checked_bytes =
171-
check_slice_size(key_bytes, <Self::Len as Unsigned>::to_usize(), "key_bytes")?;
172-
Ok(Key(checked_bytes.to_vec()))
107+
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
108+
Ok(Key(key_bytes.to_vec()))
173109
}
174110
}
175111

176-
try_from_and_to_bytes_using_sized_bytes!(Key);
177-
178112
/// A representation of an X25519 keypair according to RFC7748
179-
#[derive(Debug, PartialEq, Eq)]
113+
#[derive(Debug, PartialEq, Eq, SizedBytes, TryFromForSizedBytes)]
114+
#[ErrorType = "::generic_bytes::TryFromSizedBytesError"]
180115
pub struct X25519KeyPair {
181116
pk: Key,
182117
sk: Key,

src/lib.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
//! ## Setup
4141
//! To setup the protocol, the server begins by generating a static keypair:
4242
//! ```
43-
//! # use opaque_ke::keypair::{KeyPair, X25519KeyPair, SizedBytes};
43+
//! # use opaque_ke::keypair::{KeyPair, X25519KeyPair};
4444
//! # use opaque_ke::errors::ProtocolError;
4545
//! # use opaque_ke::ciphersuite::CipherSuite;
4646
//! # struct Default;
@@ -72,7 +72,7 @@
7272
//! # use opaque_ke::{
7373
//! # errors::ProtocolError,
7474
//! # opaque::ServerRegistration,
75-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
75+
//! # keypair::{KeyPair, X25519KeyPair},
7676
//! # slow_hash::NoOpHash,
7777
//! # };
7878
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -102,7 +102,7 @@
102102
//! # use opaque_ke::{
103103
//! # errors::ProtocolError,
104104
//! # opaque::ClientRegistration,
105-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
105+
//! # keypair::{KeyPair, X25519KeyPair},
106106
//! # slow_hash::NoOpHash,
107107
//! # };
108108
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -135,7 +135,7 @@
135135
//! # use opaque_ke::{
136136
//! # errors::ProtocolError,
137137
//! # opaque::{ClientRegistration, ServerRegistration},
138-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
138+
//! # keypair::{KeyPair, X25519KeyPair},
139139
//! # slow_hash::NoOpHash,
140140
//! # };
141141
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -169,7 +169,7 @@
169169
//! # use opaque_ke::{
170170
//! # errors::ProtocolError,
171171
//! # opaque::{ClientRegistration, ServerRegistration},
172-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
172+
//! # keypair::{KeyPair, X25519KeyPair},
173173
//! # slow_hash::NoOpHash,
174174
//! # };
175175
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -211,7 +211,7 @@
211211
//! # use opaque_ke::{
212212
//! # errors::ProtocolError,
213213
//! # opaque::{ClientRegistration, ServerRegistration, ServerLogin, LoginThirdMessage},
214-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
214+
//! # keypair::{KeyPair, X25519KeyPair},
215215
//! # slow_hash::NoOpHash,
216216
//! # };
217217
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -241,7 +241,7 @@
241241
//! # use opaque_ke::{
242242
//! # errors::ProtocolError,
243243
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, LoginThirdMessage},
244-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
244+
//! # keypair::{KeyPair, X25519KeyPair},
245245
//! # slow_hash::NoOpHash,
246246
//! # };
247247
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -285,7 +285,7 @@
285285
//! # use opaque_ke::{
286286
//! # errors::ProtocolError,
287287
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
288-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
288+
//! # keypair::{KeyPair, X25519KeyPair},
289289
//! # slow_hash::NoOpHash,
290290
//! # };
291291
//! # use opaque_ke::ciphersuite::CipherSuite;
@@ -340,7 +340,7 @@
340340
//! # use opaque_ke::{
341341
//! # errors::ProtocolError,
342342
//! # opaque::{ClientRegistration, ServerRegistration, ClientLogin, ServerLogin, LoginThirdMessage},
343-
//! # keypair::{KeyPair, X25519KeyPair, SizedBytes},
343+
//! # keypair::{KeyPair, X25519KeyPair},
344344
//! # slow_hash::NoOpHash,
345345
//! # };
346346
//! # use opaque_ke::ciphersuite::CipherSuite;

src/opaque.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ use crate::{
1515
group::Group,
1616
hash::Hash,
1717
key_exchange::traits::{KeyExchange, ToBytes},
18-
keypair::{KeyPair, SizedBytes},
18+
keypair::{KeyPair, SizedBytesExt},
1919
oprf,
2020
serialization::{
2121
serialize, tokenize, u8_to_credential_type, CredentialType, ProtocolMessageType,
2222
},
2323
slow_hash::SlowHash,
2424
};
2525
use generic_array::{typenum::Unsigned, GenericArray};
26+
use generic_bytes::SizedBytes;
2627
use rand_core::{CryptoRng, RngCore};
2728
use std::collections::HashMap;
2829
use std::{convert::TryFrom, marker::PhantomData};
@@ -620,7 +621,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
620621
/// # Example
621622
///
622623
/// ```
623-
/// use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::{X25519KeyPair, SizedBytes}};
624+
/// use opaque_ke::{opaque::{ClientRegistration, ServerRegistration}, keypair::X25519KeyPair};
624625
/// # use opaque_ke::errors::ProtocolError;
625626
/// # use opaque_ke::keypair::KeyPair;
626627
/// use rand_core::{OsRng, RngCore};
@@ -802,7 +803,7 @@ where
802803
/// # Example
803804
///
804805
/// ```
805-
/// use opaque_ke::{opaque::*, keypair::{X25519KeyPair, SizedBytes}};
806+
/// use opaque_ke::{opaque::*, keypair::X25519KeyPair};
806807
/// # use opaque_ke::errors::ProtocolError;
807808
/// use rand_core::{OsRng, RngCore};
808809
/// use opaque_ke::ciphersuite::CipherSuite;
@@ -878,7 +879,7 @@ where
878879
/// # Example
879880
///
880881
/// ```
881-
/// use opaque_ke::{opaque::*, keypair::{KeyPair, X25519KeyPair, SizedBytes}};
882+
/// use opaque_ke::{opaque::*, keypair::{KeyPair, X25519KeyPair}};
882883
/// # use opaque_ke::errors::ProtocolError;
883884
/// use rand_core::{OsRng, RngCore};
884885
/// use opaque_ke::ciphersuite::CipherSuite;

src/serialization/tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ use crate::{
1111
traits::{KeyExchange, ToBytes},
1212
tripledh::{TripleDH, NONCE_LEN},
1313
},
14-
keypair::{KeyPair, SizedBytes, X25519KeyPair},
14+
keypair::{KeyPair, X25519KeyPair},
1515
opaque::*,
1616
serialization::{serialize, ProtocolMessageType},
1717
};
1818

1919
use curve25519_dalek::ristretto::RistrettoPoint;
20+
use generic_bytes::SizedBytes;
2021
use proptest::{collection::vec, prelude::*};
2122
use rand_core::{OsRng, RngCore};
2223

src/tests/opaque_ke_test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use crate::{
88
errors::*,
99
group::Group,
1010
key_exchange::tripledh::{TripleDH, NONCE_LEN},
11-
keypair::{Key, KeyPair, SizedBytes, X25519KeyPair},
11+
keypair::{Key, KeyPair, X25519KeyPair},
1212
opaque::*,
1313
slow_hash::NoOpHash,
1414
tests::mock_rng::CycleRng,
1515
};
1616
use curve25519_dalek::edwards::EdwardsPoint;
1717
use generic_array::GenericArray;
18+
use generic_bytes::SizedBytes;
1819
use rand_core::{OsRng, RngCore};
1920
use serde_json::Value;
2021
use std::convert::TryFrom;

0 commit comments

Comments
 (0)