Fix no_std support (#229)
This commit is contained in:
@@ -145,15 +145,20 @@ jobs:
|
||||
target:
|
||||
# for wasm
|
||||
- wasm32-unknown-unknown
|
||||
# for any no_std target
|
||||
- thumbv6m-none-eabi
|
||||
backend_feature:
|
||||
- u64_backend
|
||||
- u32_backend
|
||||
- p256,u64_backend
|
||||
frontend_feature:
|
||||
- slow-hash
|
||||
- serialize
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: hecrj/setup-rust-action@v1
|
||||
- run: rustup target add ${{ matrix.target }}
|
||||
- run: cargo build --verbose --target=${{ matrix.target }} --no-default-features --features ${{ matrix.backend_feature }}
|
||||
- run: cargo build --verbose --target=${{ matrix.target }} --no-default-features --features ${{ matrix.frontend_feature }} --features ${{ matrix.backend_feature }}
|
||||
|
||||
benches:
|
||||
name: cargo bench compilation
|
||||
|
||||
+16
-13
@@ -9,6 +9,7 @@ authors = ["Kevin Lewi <[email protected]>", "François Garillot <[email protected]>"]
|
||||
license = "MIT"
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
resolver = "2"
|
||||
|
||||
[features]
|
||||
default = ["u64_backend", "serialize"]
|
||||
@@ -17,32 +18,33 @@ p256 = ["num-bigint", "num-integer", "num-traits", "once_cell", "p256_"]
|
||||
bench = []
|
||||
u64_backend = ["curve25519-dalek/u64_backend"]
|
||||
u32_backend = ["curve25519-dalek/u32_backend"]
|
||||
std = ["curve25519-dalek/std"]
|
||||
std = ["curve25519-dalek/std", "getrandom", "rand/std", "rand/std_rng", "num-bigint/std", "num-integer/std", "num-traits/std"]
|
||||
serialize = ["serde", "base64", "generic-array/serde", "curve25519-dalek/serde"]
|
||||
|
||||
[dependencies]
|
||||
argon2 = { version = "0.2", optional = true }
|
||||
base64 = { version = "0.13", optional = true }
|
||||
argon2 = { version = "0.2", default-features = false, optional = true }
|
||||
base64 = { version = "0.13", default-features = false, features = ["alloc"], optional = true }
|
||||
constant_time_eq = "0.1"
|
||||
curve25519-dalek = { version = "3", default-features = false }
|
||||
digest = "0.9"
|
||||
displaydoc = "0.2"
|
||||
displaydoc = { version = "0.2", default-features = false }
|
||||
generic-array = "0.14"
|
||||
generic-bytes = { version = "0.1" }
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
getrandom = { version = "0.2", optional = true }
|
||||
hkdf = "0.11"
|
||||
hmac = "0.11"
|
||||
num-bigint = { version = "0.4", optional = true }
|
||||
num-integer = { version = "0.1", optional = true }
|
||||
num-traits = { version = "0.2", optional = true }
|
||||
once_cell = { version = "1", optional = true }
|
||||
p256_ = { package = "p256", version = "0.9", optional = true }
|
||||
num-bigint = { version = "0.4", default-features = false, optional = true }
|
||||
num-integer = { version = "0.1", default-features = false, optional = true }
|
||||
num-traits = { version = "0.2", default-features = false, optional = true }
|
||||
once_cell = { version = "1", default-features = false, optional = true }
|
||||
p256_ = { package = "p256", version = "0.9", default-features = false, features = ["arithmetic", "zeroize"], optional = true }
|
||||
rand = { version = "0.8", default-features = false }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
serde = { version = "1", default-features = false, features = ["alloc", "derive"], optional = true }
|
||||
subtle = { version = "2.3", default-features = false }
|
||||
thiserror = "1"
|
||||
zeroize = { version = "1", features = ["zeroize_derive"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
getrandom = { version = "0.2", features = ["js"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
base64 = "0.13"
|
||||
bincode = "1"
|
||||
@@ -50,6 +52,7 @@ chacha20poly1305 = "0.8"
|
||||
criterion = "0.3"
|
||||
hex = "0.4"
|
||||
lazy_static = "1"
|
||||
opaque-ke = { path = "", default-features = false, features = ["std"] }
|
||||
serde_json = "1"
|
||||
sha2 = "0.9"
|
||||
proptest = "1"
|
||||
|
||||
+7
-8
@@ -8,7 +8,7 @@ use crate::{
|
||||
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
|
||||
group::Group,
|
||||
hash::Hash,
|
||||
keypair::{KeyPair, PrivateKey, PublicKey},
|
||||
keypair::{KeyPair, PublicKey},
|
||||
opaque::{bytestrings_from_identifiers, Identifiers},
|
||||
};
|
||||
use alloc::vec;
|
||||
@@ -16,7 +16,6 @@ use alloc::vec::Vec;
|
||||
use core::convert::TryFrom;
|
||||
use digest::Digest;
|
||||
use generic_array::{typenum::Unsigned, GenericArray};
|
||||
use generic_bytes::SizedBytes;
|
||||
use hkdf::Hkdf;
|
||||
use hmac::{Hmac, Mac, NewMac};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
@@ -35,7 +34,7 @@ fn build_inner_envelope_internal<CS: CipherSuite>(
|
||||
nonce: &[u8],
|
||||
) -> Result<PublicKey<CS::KeGroup>, ProtocolError> {
|
||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||
let mut keypair_seed = vec![0u8; <PrivateKey<CS::KeGroup> as SizedBytes>::Len::to_usize()];
|
||||
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||
@@ -53,7 +52,7 @@ fn recover_keys_internal<CS: CipherSuite>(
|
||||
nonce: &[u8],
|
||||
) -> Result<KeyPair<CS::KeGroup>, ProtocolError> {
|
||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||
let mut keypair_seed = vec![0u8; <PrivateKey<CS::KeGroup> as SizedBytes>::Len::to_usize()];
|
||||
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||
@@ -153,15 +152,15 @@ type SealResult<CS> = (
|
||||
|
||||
impl<CS: CipherSuite> Envelope<CS> {
|
||||
fn hmac_key_size() -> usize {
|
||||
<CS::Hash as Digest>::OutputSize::to_usize()
|
||||
<CS::Hash as Digest>::OutputSize::USIZE
|
||||
}
|
||||
|
||||
fn export_key_size() -> usize {
|
||||
<CS::Hash as Digest>::OutputSize::to_usize()
|
||||
<CS::Hash as Digest>::OutputSize::USIZE
|
||||
}
|
||||
|
||||
pub(crate) fn len() -> usize {
|
||||
<CS::Hash as Digest>::OutputSize::to_usize() + NONCE_LEN
|
||||
<CS::Hash as Digest>::OutputSize::USIZE + NONCE_LEN
|
||||
}
|
||||
|
||||
pub(crate) fn serialize(&self) -> Vec<u8> {
|
||||
@@ -201,7 +200,7 @@ impl<CS: CipherSuite> Envelope<CS> {
|
||||
nonce: vec![0u8; NONCE_LEN],
|
||||
hmac: GenericArray::clone_from_slice(&vec![
|
||||
0u8;
|
||||
<CS::Hash as Digest>::OutputSize::to_usize()
|
||||
<CS::Hash as Digest>::OutputSize::USIZE
|
||||
]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,24 +296,6 @@ impl ProtocolError {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for InternalPakeError<T> {
|
||||
fn from(_: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
InternalPakeError::InvalidByteSequence
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for PakeError<T> {
|
||||
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
PakeError::CryptoError(e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<generic_bytes::TryFromSizedBytesError> for ProtocolError<T> {
|
||||
fn from(e: generic_bytes::TryFromSizedBytesError) -> Self {
|
||||
PakeError::CryptoError(e.into()).into()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod utils {
|
||||
use super::*;
|
||||
|
||||
|
||||
+2
-2
@@ -31,8 +31,8 @@ pub fn expand_message_xmd<H: Hash>(
|
||||
dst: &[u8],
|
||||
len_in_bytes: usize,
|
||||
) -> Result<Vec<u8>, ProtocolError> {
|
||||
let b_in_bytes = <H as Digest>::OutputSize::to_usize();
|
||||
let r_in_bytes = <H as BlockInput>::BlockSize::to_usize();
|
||||
let b_in_bytes = <H as Digest>::OutputSize::USIZE;
|
||||
let r_in_bytes = <H as BlockInput>::BlockSize::USIZE;
|
||||
|
||||
let ell = div_ceil(len_in_bytes, b_in_bytes);
|
||||
if ell > 255 {
|
||||
|
||||
+50
-35
@@ -18,7 +18,7 @@ use generic_array::{ArrayLength, GenericArray};
|
||||
use num_bigint::{BigInt, Sign};
|
||||
use num_integer::Integer;
|
||||
use num_traits::{One, ToPrimitive};
|
||||
use once_cell::sync::Lazy;
|
||||
use once_cell::unsync::Lazy;
|
||||
use p256_::elliptic_curve::group::prime::PrimeCurveAffine;
|
||||
use p256_::elliptic_curve::group::GroupEncoding;
|
||||
use p256_::elliptic_curve::sec1::{FromEncodedPoint, ToEncodedPoint};
|
||||
@@ -27,50 +27,41 @@ use p256_::elliptic_curve::Field;
|
||||
use p256_::{AffinePoint, EncodedPoint, ProjectivePoint};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-8.2
|
||||
// `p: 2^256 - 2^224 + 2^192 + 2^96 - 1`
|
||||
const P: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::from_str(
|
||||
"115792089210356248762697446949407573530086143415290314195533631308867097853951",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
// `A: -3`
|
||||
const A: Lazy<BigInt> = Lazy::new(|| BigInt::from(-3));
|
||||
// `B: 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b`
|
||||
const B: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::parse_bytes(
|
||||
b"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
|
||||
16,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
// `L: 48`
|
||||
pub const L: usize = 48;
|
||||
// `Z: -10`
|
||||
const Z: Lazy<BigInt> = Lazy::new(|| BigInt::from(-10));
|
||||
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#[{%22num%22:211,%22gen%22:0},{%22name%22:%22XYZ%22},70,700,0]
|
||||
// P-256 `n` is defined as `115792089210356248762697446949407573529996955224135760342 422259061068512044369`
|
||||
pub const N: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::from_str(
|
||||
"115792089210356248762697446949407573529996955224135760342422259061068512044369",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
#[cfg(feature = "p256")]
|
||||
impl Group for ProjectivePoint {
|
||||
const SUITE_ID: usize = 0x0003;
|
||||
|
||||
// Implements the `hash_to_curve()` function from
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
||||
fn map_to_curve<H: Hash>(msg: &[u8], dst: &[u8]) -> Result<Self, ProtocolError> {
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-8.2
|
||||
// `p: 2^256 - 2^224 + 2^192 + 2^96 - 1`
|
||||
const P: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::from_str(
|
||||
"115792089210356248762697446949407573530086143415290314195533631308867097853951",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
// `A: -3`
|
||||
const A: Lazy<BigInt> = Lazy::new(|| BigInt::from(-3));
|
||||
// `B: 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b`
|
||||
const B: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::parse_bytes(
|
||||
b"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
|
||||
16,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
// `Z: -10`
|
||||
const Z: Lazy<BigInt> = Lazy::new(|| BigInt::from(-10));
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
||||
// `hash_to_curve` calls `hash_to_field` with a `count` of `2`
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
||||
// `hash_to_field` calls `expand_message` with a `len_in_bytes` of `count * L`
|
||||
let uniform_bytes =
|
||||
super::expand::expand_message_xmd::<H>(msg, dst, 2 * crate::group::p256::L)?;
|
||||
let uniform_bytes = super::expand::expand_message_xmd::<H>(msg, dst, 2 * L)?;
|
||||
|
||||
// map to curve
|
||||
let (q0x, q0y) = map_to_curve_simple_swu(&uniform_bytes[..L], &A, &B, &P, &Z);
|
||||
@@ -93,12 +84,20 @@ impl Group for ProjectivePoint {
|
||||
// Implements the `HashToScalar()` function from
|
||||
// https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-07.html#section-4.3
|
||||
fn hash_to_scalar<H: Hash>(input: &[u8], dst: &[u8]) -> Result<Self::Scalar, ProtocolError> {
|
||||
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#[{%22num%22:211,%22gen%22:0},{%22name%22:%22XYZ%22},70,700,0]
|
||||
// P-256 `n` is defined as `115792089210356248762697446949407573529996955224135760342 422259061068512044369`
|
||||
const N: once_cell::unsync::Lazy<BigInt> = once_cell::unsync::Lazy::new(|| {
|
||||
BigInt::from_str(
|
||||
"115792089210356248762697446949407573529996955224135760342422259061068512044369",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
||||
// `HashToScalar` is `hash_to_field`
|
||||
let uniform_bytes =
|
||||
super::expand::expand_message_xmd::<H>(input, dst, crate::group::p256::L)?;
|
||||
let uniform_bytes = super::expand::expand_message_xmd::<H>(input, dst, L)?;
|
||||
let mut bytes = BigInt::from_bytes_be(Sign::Plus, &uniform_bytes)
|
||||
.mod_floor(&crate::group::p256::N)
|
||||
.mod_floor(&N)
|
||||
.to_bytes_be()
|
||||
.1;
|
||||
bytes.resize(32, 0);
|
||||
@@ -410,6 +409,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn map_to_curve_simple_swu() {
|
||||
const P: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::from_str(
|
||||
"115792089210356248762697446949407573530086143415290314195533631308867097853951",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
const A: Lazy<BigInt> = Lazy::new(|| BigInt::from(-3));
|
||||
const B: Lazy<BigInt> = Lazy::new(|| {
|
||||
BigInt::parse_bytes(
|
||||
b"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
|
||||
16,
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
const Z: Lazy<BigInt> = Lazy::new(|| BigInt::from(-10));
|
||||
|
||||
// Test vectors taken from https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-J.1.1
|
||||
let test_vectors = alloc::vec![
|
||||
Params {
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
key_exchange::traits::{
|
||||
FromBytes, GenerateKe2Result, GenerateKe3Result, KeyExchange, ToBytes, ToBytesWithPointers,
|
||||
},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey, SizedBytesExt},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey},
|
||||
serialization::serialize,
|
||||
};
|
||||
use alloc::vec;
|
||||
@@ -26,7 +26,6 @@ use generic_array::{
|
||||
typenum::{Unsigned, U32},
|
||||
ArrayLength, GenericArray,
|
||||
};
|
||||
use generic_bytes::SizedBytes;
|
||||
use hkdf::Hkdf;
|
||||
use hmac::{Hmac, Mac, NewMac};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
@@ -214,9 +213,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
}
|
||||
|
||||
fn ke2_message_size() -> usize {
|
||||
NonceLen::to_usize()
|
||||
+ <G as Group>::ElemLen::to_usize()
|
||||
+ <<D as FixedOutput>::OutputSize as Unsigned>::to_usize()
|
||||
NonceLen::USIZE + <G as Group>::ElemLen::USIZE + <D as FixedOutput>::OutputSize::USIZE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +257,9 @@ pub struct Ke1Message<G: Group> {
|
||||
|
||||
impl<G: Group> FromBytes for Ke1State<G> {
|
||||
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
||||
let key_len = <G as Group>::ElemLen::to_usize();
|
||||
let key_len = <G as Group>::ElemLen::USIZE;
|
||||
|
||||
let nonce_len = NonceLen::to_usize();
|
||||
let nonce_len = NonceLen::USIZE;
|
||||
let checked_bytes = check_slice_size_atleast(bytes, key_len + nonce_len, "ke1_state")?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -283,11 +280,8 @@ impl<G: Group> ToBytesWithPointers for Ke1State<G> {
|
||||
#[cfg(test)]
|
||||
fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
||||
vec![
|
||||
(
|
||||
self.client_e_sk.as_ptr(),
|
||||
<PrivateKey<G> as SizedBytes>::Len::to_usize(),
|
||||
),
|
||||
(self.client_nonce.as_ptr(), NonceLen::to_usize()),
|
||||
(self.client_e_sk.as_ptr(), G::ScalarLen::USIZE),
|
||||
(self.client_nonce.as_ptr(), NonceLen::USIZE),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -300,10 +294,10 @@ impl<G: Group> ToBytes for Ke1Message<G> {
|
||||
|
||||
impl<G: Group> FromBytes for Ke1Message<G> {
|
||||
fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, PakeError> {
|
||||
let nonce_len = NonceLen::to_usize();
|
||||
let nonce_len = NonceLen::USIZE;
|
||||
let checked_nonce = check_slice_size(
|
||||
ke1_message_bytes,
|
||||
nonce_len + <G as Group>::ElemLen::to_usize(),
|
||||
nonce_len + <G as Group>::ElemLen::USIZE,
|
||||
"ke1_message nonce",
|
||||
)?;
|
||||
|
||||
@@ -351,9 +345,9 @@ impl<HashLen: ArrayLength<u8>> ToBytesWithPointers for Ke2State<HashLen> {
|
||||
#[cfg(test)]
|
||||
fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
||||
vec![
|
||||
(self.km3.as_ptr(), HashLen::to_usize()),
|
||||
(self.hashed_transcript.as_ptr(), HashLen::to_usize()),
|
||||
(self.session_key.as_ptr(), HashLen::to_usize()),
|
||||
(self.km3.as_ptr(), HashLen::USIZE),
|
||||
(self.hashed_transcript.as_ptr(), HashLen::USIZE),
|
||||
(self.session_key.as_ptr(), HashLen::USIZE),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -370,7 +364,7 @@ pub struct Ke2Message<G: Group, HashLen: ArrayLength<u8>> {
|
||||
|
||||
impl<HashLen: ArrayLength<u8>> FromBytes for Ke2State<HashLen> {
|
||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
||||
let hash_len = HashLen::to_usize();
|
||||
let hash_len = HashLen::USIZE;
|
||||
let checked_bytes = check_slice_size(input, 3 * hash_len, "ke2_state")?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -397,8 +391,8 @@ impl<G: Group, HashLen: ArrayLength<u8>> Ke2Message<G, HashLen> {
|
||||
|
||||
impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
||||
let key_len = <G as Group>::ElemLen::to_usize();
|
||||
let nonce_len = NonceLen::to_usize();
|
||||
let key_len = <G as Group>::ElemLen::USIZE;
|
||||
let nonce_len = NonceLen::USIZE;
|
||||
let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
|
||||
|
||||
let unchecked_server_e_pk = check_slice_size_atleast(
|
||||
@@ -408,7 +402,7 @@ impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
||||
)?;
|
||||
let checked_mac = check_slice_size(
|
||||
&unchecked_server_e_pk[key_len..],
|
||||
HashLen::to_usize(),
|
||||
HashLen::USIZE,
|
||||
"ke1_message mac",
|
||||
)?;
|
||||
|
||||
@@ -468,7 +462,7 @@ impl<HashLen: ArrayLength<u8>> ToBytes for Ke3Message<HashLen> {
|
||||
|
||||
impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
||||
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
||||
let checked_bytes = check_slice_size(bytes, HashLen::to_usize(), "ke3_message")?;
|
||||
let checked_bytes = check_slice_size(bytes, HashLen::USIZE, "ke3_message")?;
|
||||
|
||||
Ok(Self {
|
||||
mac: GenericArray::clone_from_slice(checked_bytes),
|
||||
@@ -513,14 +507,14 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
|
||||
&handshake_secret,
|
||||
STR_SERVER_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
<D as Digest>::OutputSize::USIZE,
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
let km3 = hkdf_expand_label::<D>(
|
||||
&handshake_secret,
|
||||
STR_CLIENT_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
<D as Digest>::OutputSize::USIZE,
|
||||
)
|
||||
.map_err(ProtocolError::into_custom)?;
|
||||
|
||||
@@ -577,13 +571,13 @@ fn derive_secrets<D: Hash>(
|
||||
hkdf,
|
||||
label,
|
||||
hashed_derivation_transcript,
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
<D as Digest>::OutputSize::USIZE,
|
||||
)
|
||||
}
|
||||
|
||||
// Generate a random nonce up to NonceLen::to_usize() bytes.
|
||||
// Generate a random nonce up to NonceLen::USIZE bytes.
|
||||
fn generate_nonce<R: RngCore + CryptoRng>(rng: &mut R) -> GenericArray<u8, NonceLen> {
|
||||
let mut nonce_bytes = vec![0u8; NonceLen::to_usize()];
|
||||
let mut nonce_bytes = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut nonce_bytes);
|
||||
GenericArray::clone_from_slice(&nonce_bytes)
|
||||
}
|
||||
|
||||
+35
-46
@@ -9,32 +9,14 @@
|
||||
|
||||
use crate::errors::{InternalPakeError, ProtocolError};
|
||||
use crate::group::Group;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::Debug;
|
||||
use core::ops::Deref;
|
||||
#[cfg(test)]
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use generic_bytes::{SizedBytes, TryFromSizedBytesError};
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
use proptest::prelude::*;
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
use rand::{rngs::StdRng, SeedableRng};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use zeroize::Zeroize;
|
||||
|
||||
/// Convenience extension trait of SizedBytes
|
||||
pub trait SizedBytesExt: SizedBytes {
|
||||
/// Convert from bytes
|
||||
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
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
@@ -142,17 +124,20 @@ impl<G: Group> KeyPair<G> {
|
||||
#[cfg(test)]
|
||||
pub fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
||||
alloc::vec![
|
||||
(self.pk.as_ptr(), G::ElemLen::to_usize()),
|
||||
(self.sk.as_ptr(), G::ScalarLen::to_usize()),
|
||||
(self.pk.as_ptr(), G::ElemLen::USIZE),
|
||||
(self.sk.as_ptr(), G::ScalarLen::USIZE),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
#[cfg(test)]
|
||||
impl<G: Group + Debug> KeyPair<G> {
|
||||
/// Test-only strategy returning a proptest Strategy based on
|
||||
/// generate_random
|
||||
fn uniform_keypair_strategy() -> BoxedStrategy<Self> {
|
||||
fn uniform_keypair_strategy() -> proptest::prelude::BoxedStrategy<Self> {
|
||||
use proptest::prelude::*;
|
||||
use rand::{rngs::StdRng, SeedableRng};
|
||||
|
||||
// The no_shrink is because keypairs should be fixed -- shrinking would cause a different
|
||||
// keypair to be generated, which appears to not be very useful.
|
||||
any::<[u8; 32]>()
|
||||
@@ -223,13 +208,9 @@ impl<L: ArrayLength<u8>> Deref for Key<L> {
|
||||
|
||||
// Don't make it implement SizedBytes so that it's not constructible outside of this module.
|
||||
impl<L: ArrayLength<u8>> Key<L> {
|
||||
fn to_arr(&self) -> GenericArray<u8, L> {
|
||||
GenericArray::clone_from_slice(&self.0[..])
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn from_arr(key_bytes: &GenericArray<u8, L>) -> Result<Self, TryFromSizedBytesError> {
|
||||
Ok(Key(key_bytes.to_owned()))
|
||||
/// Convert to bytes
|
||||
pub fn to_arr(&self) -> GenericArray<u8, L> {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,15 +249,19 @@ impl<G: Group> Deref for PrivateKey<G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> SizedBytes for PrivateKey<G> {
|
||||
type Len = G::ScalarLen;
|
||||
|
||||
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
||||
self.0.to_arr()
|
||||
impl<G: Group> PrivateKey<G> {
|
||||
/// Convert from bytes
|
||||
pub fn from_arr(key_bytes: GenericArray<u8, G::ScalarLen>) -> Self {
|
||||
PrivateKey(Key(key_bytes))
|
||||
}
|
||||
|
||||
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
||||
Ok(PrivateKey(Key::from_arr(key_bytes)?))
|
||||
/// Convert from slice
|
||||
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
|
||||
if key_bytes.len() == G::ScalarLen::USIZE {
|
||||
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
||||
} else {
|
||||
Err(InternalPakeError::InvalidByteSequence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,15 +344,19 @@ impl<G: Group> Deref for PublicKey<G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> SizedBytes for PublicKey<G> {
|
||||
type Len = G::ElemLen;
|
||||
|
||||
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
||||
self.0.to_arr()
|
||||
impl<G: Group> PublicKey<G> {
|
||||
/// Convert from bytes
|
||||
pub fn from_arr(key_bytes: GenericArray<u8, G::ElemLen>) -> Self {
|
||||
Self(Key(key_bytes))
|
||||
}
|
||||
|
||||
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
||||
Ok(PublicKey(Key::from_arr(key_bytes)?))
|
||||
/// Convert from slice
|
||||
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
|
||||
if key_bytes.len() == G::ElemLen::USIZE {
|
||||
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
||||
} else {
|
||||
Err(InternalPakeError::InvalidByteSequence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,11 +367,12 @@ mod tests {
|
||||
use core::slice::from_raw_parts;
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
use generic_array::typenum::Unsigned;
|
||||
use proptest::prelude::*;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
#[test]
|
||||
fn test_zeroize_key() -> Result<(), ProtocolError> {
|
||||
let key_len = <RistrettoPoint as Group>::ElemLen::to_usize();
|
||||
let key_len = <RistrettoPoint as Group>::ElemLen::USIZE;
|
||||
let mut key = Key::<<RistrettoPoint as Group>::ElemLen>(GenericArray::clone_from_slice(
|
||||
&alloc::vec![
|
||||
1u8;
|
||||
@@ -415,7 +405,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
proptest! {
|
||||
#[test]
|
||||
fn test_ristretto_check(kp in KeyPair::<RistrettoPoint>::uniform_keypair_strategy()) {
|
||||
@@ -505,7 +494,7 @@ mod tests {
|
||||
|
||||
let sk = RistrettoPoint::random_nonzero_scalar(&mut OsRng);
|
||||
let sk_bytes = RistrettoPoint::scalar_as_bytes(sk);
|
||||
let sk = RemoteKey(PrivateKey::from_arr(&sk_bytes).unwrap());
|
||||
let sk = RemoteKey(PrivateKey::from_arr(sk_bytes));
|
||||
let keypair = KeyPair::from_private_key(sk).unwrap();
|
||||
|
||||
let server_setup = ServerSetup::<Default, RemoteKey>::new_with_key(&mut OsRng, keypair);
|
||||
|
||||
+2
-4
@@ -748,7 +748,6 @@
|
||||
//! ```
|
||||
//! # use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
//! # use generic_array::{GenericArray, typenum::U32};
|
||||
//! # use generic_bytes::SizedBytes;
|
||||
//! # use opaque_ke::{CipherSuite, errors::{InternalPakeError}, keypair::{KeyPair, PrivateKey, PublicKey, SecretKey}, ServerSetup};
|
||||
//! # use rand::rngs::OsRng;
|
||||
//! # use zeroize::Zeroize;
|
||||
@@ -781,8 +780,7 @@
|
||||
//! fn public_key(
|
||||
//! &self
|
||||
//! ) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
|
||||
//! let pk = YourRemoteKey::public_key(self).map_err(InternalPakeError::Custom)?;
|
||||
//! PublicKey::from_arr(&pk).map_err(InternalPakeError::from)
|
||||
//! YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalPakeError::Custom)
|
||||
//! }
|
||||
//!
|
||||
//! fn serialize(&self) -> Vec<u8> {
|
||||
@@ -796,7 +794,7 @@
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! # let remote_key = YourRemoteKey(PrivateKey::from_arr(&GenericArray::default()).unwrap());
|
||||
//! # let remote_key = YourRemoteKey(PrivateKey::from_arr(GenericArray::default()));
|
||||
//! let keypair = KeyPair::from_private_key(remote_key).unwrap();
|
||||
//! let server_setup = ServerSetup::<Default, YourRemoteKey>::new_with_key(&mut OsRng, keypair);
|
||||
//! ```
|
||||
|
||||
+10
-11
@@ -14,13 +14,12 @@ use crate::{
|
||||
},
|
||||
group::Group,
|
||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytes},
|
||||
keypair::{KeyPair, PublicKey, SecretKey, SizedBytesExt},
|
||||
keypair::{KeyPair, PublicKey, SecretKey},
|
||||
opaque::ServerSetup,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use digest::Digest;
|
||||
use generic_array::{typenum::Unsigned, GenericArray};
|
||||
use generic_bytes::SizedBytes;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
// Messages
|
||||
@@ -57,7 +56,7 @@ impl<CS: CipherSuite> RegistrationRequest<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::to_usize();
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
let checked_slice = check_slice_size(input, elem_len, "first_message_bytes")?;
|
||||
// Check that the message is actually containing an element of the
|
||||
// correct subgroup
|
||||
@@ -107,8 +106,8 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::to_usize();
|
||||
let key_len = <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize();
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
let key_len = <CS::KeGroup as Group>::ElemLen::USIZE;
|
||||
let checked_slice =
|
||||
check_slice_size(input, elem_len + key_len, "registration_response_bytes")?;
|
||||
|
||||
@@ -177,8 +176,8 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let key_len = <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize();
|
||||
let hash_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
||||
let key_len = <CS::KeGroup as Group>::ElemLen::USIZE;
|
||||
let hash_len = <CS::Hash as Digest>::OutputSize::USIZE;
|
||||
let checked_slice =
|
||||
check_slice_size_atleast(input, key_len + hash_len, "registration_upload_bytes")?;
|
||||
let envelope = Envelope::<CS>::deserialize(&checked_slice[key_len + hash_len..])?;
|
||||
@@ -198,7 +197,7 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
rng: &mut R,
|
||||
server_setup: &ServerSetup<CS, S>,
|
||||
) -> Self {
|
||||
let mut masking_key = alloc::vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
let mut masking_key = alloc::vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
Self {
|
||||
@@ -245,7 +244,7 @@ impl<CS: CipherSuite> CredentialRequest<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::to_usize();
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
|
||||
let checked_slice = check_slice_size_atleast(input, elem_len, "login_first_message_bytes")?;
|
||||
|
||||
@@ -327,8 +326,8 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::to_usize();
|
||||
let key_len = <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize();
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
let key_len = <CS::KeGroup as Group>::ElemLen::USIZE;
|
||||
let nonce_len: usize = 32;
|
||||
let envelope_len = Envelope::<CS>::len();
|
||||
let masked_response_len = key_len + envelope_len;
|
||||
|
||||
+13
-17
@@ -24,7 +24,6 @@ use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
use digest::Digest;
|
||||
use generic_array::{typenum::Unsigned, GenericArray};
|
||||
use generic_bytes::SizedBytes;
|
||||
use hkdf::Hkdf;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use zeroize::Zeroize;
|
||||
@@ -69,7 +68,7 @@ impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
rng: &mut R,
|
||||
keypair: KeyPair<CS::KeGroup, S>,
|
||||
) -> Self {
|
||||
let mut seed = vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
let mut seed = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||
rng.fill_bytes(&mut seed);
|
||||
|
||||
Self {
|
||||
@@ -91,8 +90,8 @@ impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError<S::Error>> {
|
||||
let seed_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
||||
let key_len = <PrivateKey<CS::KeGroup> as SizedBytes>::Len::to_usize();
|
||||
let seed_len = <CS::Hash as Digest>::OutputSize::USIZE;
|
||||
let key_len = <CS::KeGroup as Group>::ScalarLen::USIZE;
|
||||
let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -149,8 +148,8 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::to_usize();
|
||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::to_usize();
|
||||
let elem_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||
let min_expected_len = elem_len + scalar_len;
|
||||
let checked_slice = (if input.len() <= min_expected_len {
|
||||
Err(InternalPakeError::SizeError {
|
||||
@@ -332,7 +331,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
|
||||
#[cfg_attr(not(test), allow(unused_variables))]
|
||||
let (randomized_pwd, h) = Hkdf::<CS::Hash>::extract(None, &password_derived_key);
|
||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||
h.expand(STR_MASKING_KEY, &mut masking_key)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
|
||||
@@ -490,7 +489,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::to_usize();
|
||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||
let checked_slice = (if input.len() <= scalar_len {
|
||||
Err(InternalPakeError::SizeError {
|
||||
name: "client_login_bytes",
|
||||
@@ -664,7 +663,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
)?;
|
||||
|
||||
let h = Hkdf::<CS::Hash>::new(None, &password_derived_key);
|
||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||
h.expand(STR_MASKING_KEY, &mut masking_key)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
|
||||
@@ -1029,7 +1028,7 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
|
||||
oprf_seed: &GenericArray<u8, D::OutputSize>,
|
||||
credential_identifier: &[u8],
|
||||
) -> Result<G::Scalar, ProtocolError> {
|
||||
let mut ikm = vec![0u8; <PrivateKey<G> as SizedBytes>::Len::to_usize()];
|
||||
let mut ikm = vec![0u8; G::ScalarLen::USIZE];
|
||||
Hkdf::<D>::from_prk(oprf_seed)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?
|
||||
.expand(&[credential_identifier, STR_OPRF_KEY].concat(), &mut ikm)
|
||||
@@ -1043,8 +1042,7 @@ fn mask_response<CS: CipherSuite>(
|
||||
server_s_pk: &PublicKey<CS::KeGroup>,
|
||||
envelope: &Envelope<CS>,
|
||||
) -> Result<Vec<u8>, ProtocolError> {
|
||||
let mut xor_pad =
|
||||
vec![0u8; <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
||||
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?
|
||||
.expand(
|
||||
@@ -1067,8 +1065,7 @@ fn unmask_response<CS: CipherSuite>(
|
||||
masking_nonce: &[u8],
|
||||
masked_response: &[u8],
|
||||
) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError> {
|
||||
let mut xor_pad =
|
||||
vec![0u8; <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
||||
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?
|
||||
.expand(
|
||||
@@ -1081,9 +1078,8 @@ fn unmask_response<CS: CipherSuite>(
|
||||
.zip(masked_response.iter())
|
||||
.map(|(&x1, &x2)| x1 ^ x2)
|
||||
.collect();
|
||||
let key_len = <PublicKey<CS::KeGroup> as SizedBytes>::Len::to_usize();
|
||||
let unchecked_server_s_pk =
|
||||
PublicKey::from_arr(&GenericArray::clone_from_slice(&plaintext[..key_len]))?;
|
||||
let key_len = <CS::KeGroup as Group>::ElemLen::USIZE;
|
||||
let unchecked_server_s_pk = PublicKey::from_bytes(&plaintext[..key_len])?;
|
||||
let envelope = Envelope::deserialize(&plaintext[key_len..])?;
|
||||
|
||||
// Ensure that public key is valid
|
||||
|
||||
+11
-15
@@ -12,7 +12,7 @@ use crate::{
|
||||
traits::{FromBytes, KeyExchange, ToBytes},
|
||||
tripledh::{NonceLen, TripleDH},
|
||||
},
|
||||
keypair::{KeyPair, PublicKey},
|
||||
keypair::KeyPair,
|
||||
serialization::{i2osp, os2ip, serialize},
|
||||
*,
|
||||
};
|
||||
@@ -23,7 +23,6 @@ use alloc::vec::Vec;
|
||||
|
||||
use curve25519_dalek::{ristretto::RistrettoPoint, traits::Identity};
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_bytes::SizedBytes;
|
||||
use proptest::{collection::vec, prelude::*};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
|
||||
@@ -79,8 +78,8 @@ fn server_registration_roundtrip() {
|
||||
|
||||
// Construct a mock envelope
|
||||
let mut mock_envelope_bytes = Vec::new();
|
||||
mock_envelope_bytes.extend_from_slice(&vec![0; NonceLen::to_usize()]); // empty nonce
|
||||
// mock_envelope_bytes.extend_from_slice(&ciphertext); // ciphertext which is an encrypted private key
|
||||
mock_envelope_bytes.extend_from_slice(&vec![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(&[0; MAC_SIZE]); // length-MAC_SIZE hmac
|
||||
|
||||
let mock_client_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
@@ -157,7 +156,7 @@ fn registration_upload_roundtrip() {
|
||||
let mut nonce = [0u8; 32];
|
||||
rng.fill_bytes(&mut nonce);
|
||||
|
||||
let mut masking_key = vec![0u8; <sha2::Sha512 as Digest>::OutputSize::to_usize()];
|
||||
let mut masking_key = vec![0u8; <sha2::Sha512 as Digest>::OutputSize::USIZE];
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
let (envelope, _, _) =
|
||||
@@ -182,7 +181,7 @@ fn credential_request_roundtrip() {
|
||||
let alpha_bytes = alpha.to_arr().to_vec();
|
||||
|
||||
let client_e_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut client_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut client_nonce);
|
||||
|
||||
let ke1m: Vec<u8> = [&client_nonce[..], &client_e_kp.public()].concat();
|
||||
@@ -217,17 +216,14 @@ fn credential_response_roundtrip() {
|
||||
let mut masking_nonce = vec![0u8; 32];
|
||||
rng.fill_bytes(&mut masking_nonce);
|
||||
|
||||
let mut masked_response = vec![
|
||||
0u8;
|
||||
<PublicKey<RistrettoPoint> as SizedBytes>::Len::to_usize()
|
||||
+ Envelope::<Default>::len()
|
||||
];
|
||||
let mut masked_response =
|
||||
vec![0u8; <RistrettoPoint as Group>::ElemLen::USIZE + Envelope::<Default>::len()];
|
||||
rng.fill_bytes(&mut masked_response);
|
||||
|
||||
let server_e_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
let mut mac = [0u8; MAC_SIZE];
|
||||
rng.fill_bytes(&mut mac);
|
||||
let mut server_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut server_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut server_nonce);
|
||||
|
||||
let ke2m: Vec<u8> = [&server_nonce[..], &server_e_kp.public(), &mac[..]].concat();
|
||||
@@ -280,7 +276,7 @@ fn client_login_roundtrip() {
|
||||
let sc = <RistrettoPoint as Group>::random_nonzero_scalar(&mut rng);
|
||||
|
||||
let client_e_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut client_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut client_nonce);
|
||||
|
||||
let serialized_credential_request = b"serialized credential_request".to_vec();
|
||||
@@ -304,7 +300,7 @@ fn ke1_message_roundtrip() {
|
||||
let mut rng = OsRng;
|
||||
|
||||
let client_e_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut client_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut client_nonce);
|
||||
|
||||
let ke1m: Vec<u8> = [&client_nonce[..], &client_e_kp.public()].concat();
|
||||
@@ -323,7 +319,7 @@ fn ke2_message_roundtrip() {
|
||||
let server_e_kp = KeyPair::<<Default as CipherSuite>::OprfGroup>::generate_random(&mut rng);
|
||||
let mut mac = [0u8; MAC_SIZE];
|
||||
rng.fill_bytes(&mut mac);
|
||||
let mut server_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut server_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut server_nonce);
|
||||
|
||||
let ke2m: Vec<u8> = [&server_nonce[..], &server_e_kp.public(), &mac[..]].concat();
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
|
||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
) -> Result<Vec<u8>, InternalPakeError> {
|
||||
let params = argon2::Argon2::default();
|
||||
let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::to_usize()];
|
||||
let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::USIZE];
|
||||
params
|
||||
.hash_password_into(
|
||||
argon2::Algorithm::Argon2id,
|
||||
|
||||
@@ -14,7 +14,6 @@ use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::slice::from_raw_parts;
|
||||
use curve25519_dalek::{ristretto::RistrettoPoint, traits::Identity};
|
||||
use generic_bytes::SizedBytes;
|
||||
use rand::rngs::OsRng;
|
||||
use serde_json::Value;
|
||||
use zeroize::Zeroize;
|
||||
@@ -149,7 +148,6 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn stringify_test_vectors(p: &TestVectorParameters) -> alloc::string::String {
|
||||
let mut s = alloc::string::String::new();
|
||||
s.push_str("{\n");
|
||||
@@ -273,7 +271,6 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> alloc::string::String {
|
||||
s
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
|
||||
use crate::{group::Group, key_exchange::tripledh::NonceLen, keypair::KeyPair};
|
||||
use generic_array::typenum::Unsigned;
|
||||
@@ -298,9 +295,9 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
|
||||
rng.fill_bytes(&mut masking_nonce);
|
||||
let mut envelope_nonce = [0u8; 32];
|
||||
rng.fill_bytes(&mut envelope_nonce);
|
||||
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut client_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut client_nonce);
|
||||
let mut server_nonce = vec![0u8; NonceLen::to_usize()];
|
||||
let mut server_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut server_nonce);
|
||||
|
||||
let fake_sk: Vec<u8> = fake_kp.private().to_vec();
|
||||
@@ -448,7 +445,6 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn generate_test_vectors() {
|
||||
let parameters = generate_parameters::<RistrettoSha5123dhNoSlowHash>();
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
// LICENSE file in the root directory of this source tree.
|
||||
|
||||
use crate::{
|
||||
ciphersuite::CipherSuite, errors::*, key_exchange::tripledh::TripleDH, keypair::PrivateKey,
|
||||
opaque::*, slow_hash::NoOpHash, tests::mock_rng::CycleRng, *,
|
||||
ciphersuite::CipherSuite, errors::*, group::Group, key_exchange::tripledh::TripleDH, opaque::*,
|
||||
slow_hash::NoOpHash, tests::mock_rng::CycleRng, *,
|
||||
};
|
||||
use alloc::string::ToString;
|
||||
use alloc::vec::Vec;
|
||||
use alloc::{format, vec};
|
||||
use curve25519_dalek::ristretto::RistrettoPoint;
|
||||
use generic_array::typenum::Unsigned;
|
||||
use generic_bytes::SizedBytes;
|
||||
use serde_json::Value;
|
||||
|
||||
// Tests
|
||||
@@ -755,7 +754,7 @@ fn populate_test_vectors<CS: CipherSuite>(values: &Value) -> TestVectorParameter
|
||||
dummy_private_key: parse_default!(
|
||||
values,
|
||||
"client_private_key",
|
||||
vec![0u8; <PrivateKey<CS::OprfGroup> as SizedBytes>::Len::to_usize()]
|
||||
vec![0u8; <CS::OprfGroup as Group>::ScalarLen::USIZE]
|
||||
),
|
||||
dummy_masking_key: parse_default!(values, "masking_key", vec![0u8; 64]),
|
||||
context: parse!(values, "Context"),
|
||||
|
||||
Reference in New Issue
Block a user