Skip to content

Commit 847ceb0

Browse files
committed
double-pipeline support
1 parent 013eec6 commit 847ceb0

File tree

1 file changed

+145
-34
lines changed

1 file changed

+145
-34
lines changed

kbkdf/src/lib.rs

Lines changed: 145 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ where
9393
/// Derives `key` from `kin` and other parameters.
9494
fn derive(
9595
&self,
96-
kin: &GenericArray<u8, Prf::KeySize>,
96+
//kin: &GenericArray<u8, Prf::KeySize>,
97+
kin: &[u8],
9798
use_l: bool,
9899
use_separator: bool,
99100
label: &[u8],
@@ -116,31 +117,61 @@ where
116117

117118
let mut ki = None;
118119
self.input_iv(&mut ki);
120+
let mut a = {
121+
let mut h = <Prf as Mac>::new_from_slice(kin).unwrap();
122+
h.update(label);
123+
h.update(&[0]);
124+
h.update(context);
125+
h.finalize().into_bytes()
126+
};
119127

120128
for counter in 1..=n {
121-
let mut h = <Prf as Mac>::new(kin);
129+
if counter > 1 {
130+
a = {
131+
let mut h = <Prf as Mac>::new_from_slice(kin).unwrap();
132+
h.update(a.as_slice());
133+
h.finalize().into_bytes()
134+
};
135+
}
122136

137+
let mut h = <Prf as Mac>::new_from_slice(kin).unwrap();
138+
139+
let mut instring = std::vec::Vec::new();
123140
if Self::FEEDBACK_KI {
124141
if let Some(ki) = ki {
142+
instring.extend_from_slice(ki.as_slice());
125143
h.update(ki.as_slice());
126144
}
127145
}
128146

129-
// counter encoded as big endian u32
130-
// Type parameter R encodes how large the value is to be (either U8, U16, U24, or U32)
131-
//
132-
// counter = 1u32 ([0, 0, 0, 1])
133-
// \-------/
134-
// R = u24
135-
h.update(&counter.to_be_bytes()[(4 - R::USIZE / 8)..]);
147+
if Self::DOUBLE_PIPELINE {
148+
instring.extend_from_slice(a.as_slice());
149+
h.update(a.as_slice());
150+
} else {
151+
// counter encoded as big endian u32
152+
// Type parameter R encodes how large the value is to be (either U8, U16, U24, or U32)
153+
//
154+
// counter = 1u32 ([0, 0, 0, 1])
155+
// \-------/
156+
// R = u24
157+
instring.extend_from_slice(&counter.to_be_bytes()[(4 - R::USIZE / 8)..]);
158+
h.update(&counter.to_be_bytes()[(4 - R::USIZE / 8)..]);
159+
}
136160

137161
// Fixed input data
162+
instring.extend_from_slice(label);
138163
h.update(label);
139164
if use_separator {
165+
instring.extend_from_slice(&[0]);
140166
h.update(&[0]);
141167
}
168+
instring.extend_from_slice(context);
142169
h.update(context);
143170
if use_l {
171+
instring.extend_from_slice(
172+
&(<KbkdfCore<K::KeySize, Prf::OutputSize> as KbkdfUser>::L::U32).to_be_bytes()
173+
[..],
174+
);
144175
h.update(
145176
&(<KbkdfCore<K::KeySize, Prf::OutputSize> as KbkdfUser>::L::U32).to_be_bytes()
146177
[..],
@@ -166,6 +197,8 @@ where
166197

167198
/// Whether the KI should be reinjected every round.
168199
const FEEDBACK_KI: bool = false;
200+
201+
const DOUBLE_PIPELINE: bool = false;
169202
}
170203

171204
pub struct Counter<Prf, K, R = U32> {
@@ -231,10 +264,41 @@ where
231264
const FEEDBACK_KI: bool = true;
232265
}
233266

267+
pub struct DoublePipeline<Prf, K, R = U32>
268+
where
269+
Prf: Mac,
270+
{
271+
_marker: PhantomData<(Prf, K, R)>,
272+
}
273+
274+
impl<Prf, K, R> Default for DoublePipeline<Prf, K, R>
275+
where
276+
Prf: Mac,
277+
{
278+
fn default() -> Self {
279+
Self {
280+
_marker: PhantomData,
281+
}
282+
}
283+
}
284+
285+
impl<Prf, K, R> Kbkdf<Prf, K, R> for DoublePipeline<Prf, K, R>
286+
where
287+
Prf: Mac + KeyInit,
288+
K: KeySizeUser,
289+
K::KeySize: ArrayLength<u8> + Mul<U8>,
290+
<K::KeySize as Mul<U8>>::Output: Unsigned,
291+
Prf::OutputSize: ArrayLength<u8> + Mul<U8>,
292+
<Prf::OutputSize as Mul<U8>>::Output: Unsigned,
293+
R: sealed::R,
294+
{
295+
const DOUBLE_PIPELINE: bool = true;
296+
}
297+
234298
#[cfg(test)]
235299
mod tests {
236-
use super::{Counter, Feedback, GenericArray, Kbkdf};
237-
use digest::consts::*;
300+
use super::{Counter, DoublePipeline, Feedback, GenericArray, Kbkdf};
301+
use digest::{consts::*, crypto_common::KeySizeUser};
238302
use hex_literal::hex;
239303

240304
#[derive(Debug)]
@@ -293,6 +357,44 @@ mod tests {
293357
},
294358
];
295359

360+
#[test]
361+
fn test_static_values_counter() {
362+
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
363+
type HmacSha512 = hmac::Hmac<sha2::Sha512>;
364+
365+
let counter = Counter::<HmacSha256, HmacSha512>::default();
366+
for (v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256.iter().zip(0..) {
367+
assert_eq!(
368+
counter.derive(v.key, v.use_l, v.use_separator, v.label, v.context,),
369+
Ok(GenericArray::<_, _>::from_slice(v.expected).clone()),
370+
"key derivation failed for (index: {i}):\n{v:x?}"
371+
);
372+
}
373+
}
374+
375+
#[test]
376+
fn test_counter_kbkdfvs() {
377+
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
378+
struct MockOutput;
379+
380+
impl KeySizeUser for MockOutput {
381+
type KeySize = U32;
382+
}
383+
384+
let counter = Counter::<HmacSha256, MockOutput>::default();
385+
// KDFCTR_gen.txt count 15
386+
assert_eq!(
387+
counter.derive(
388+
&hex!("43eef6d824fd820405626ab9b6d79f1fd04e126ab8e17729e3afc7cb5af794f8"),
389+
false,
390+
false,
391+
&hex!("5e269b5a7bdedcc3e875e2725693a257fc60011af7dcd68a3358507fe29b0659ca66951daa05a15032033650bc58a27840f8fbe9f4088b9030738f68"),
392+
&[],
393+
),
394+
Ok(GenericArray::<_, _>::from_slice(&hex!("f0a339ecbcae6add1afb27da3ba40a1320c6427a58afb9dc366b219b7eb29ecf")).clone()),
395+
);
396+
}
397+
296398
static KNOWN_VALUES_FEEDBACK_HMAC_SHA256: &[KnownValue] = &[
297399
KnownValue {
298400
iv: Some(b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
@@ -339,43 +441,52 @@ mod tests {
339441
];
340442

341443
#[test]
342-
fn test_static_values_counter() {
444+
fn test_static_values_feedback() {
343445
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
344446
type HmacSha512 = hmac::Hmac<sha2::Sha512>;
345447

346-
let counter = Counter::<HmacSha256, HmacSha512>::default();
347-
for (v, i) in KNOWN_VALUES_COUNTER_HMAC_SHA256.iter().zip(0..) {
448+
for (v, i) in KNOWN_VALUES_FEEDBACK_HMAC_SHA256.iter().zip(0..) {
449+
let feedback =
450+
Feedback::<HmacSha256, HmacSha512>::new(v.iv.map(GenericArray::from_slice));
348451
assert_eq!(
349-
counter.derive(
350-
GenericArray::from_slice(v.key),
351-
v.use_l,
352-
v.use_separator,
353-
v.label,
354-
v.context,
355-
),
356-
Ok(GenericArray::<_, U128>::from_slice(v.expected).clone()),
452+
feedback.derive(v.key, v.use_l, v.use_separator, v.label, v.context,),
453+
Ok(GenericArray::<_, _>::from_slice(v.expected).clone()),
357454
"key derivation failed for (index: {i}):\n{v:x?}"
358455
);
359456
}
360457
}
361458

459+
static KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256: &[KnownValue] = &[KnownValue {
460+
iv: None,
461+
use_l: false, //true,
462+
use_separator: true,
463+
label: &hex!("921ab061920b191de12f746ac9de08"),
464+
context: &hex!("4f2c20f01775e27bcacdc21ee4a5ff0387758f36d8ec71c7a8c8208284f650b611837e"),
465+
key: &hex!("7d4f86fdfd1c4ba04c674a68d60316d12c99c1b1f44f0a8e02bd2601377ebcd9"),
466+
expected: &hex!(
467+
"
468+
506bc2ba51410b2a6e7c05d33891520d dd5f702ad3d6203d76d8dae1216d0783
469+
d8c59fae2e821d8eff2d8ddd93a6741c 8f144fb96e9ca7d7c532468f213f5efe
470+
"
471+
),
472+
}];
473+
362474
#[test]
363-
fn test_static_values_feedback() {
475+
fn test_static_values_double_pipeline() {
364476
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
365477
type HmacSha512 = hmac::Hmac<sha2::Sha512>;
366478

367-
for (v, i) in KNOWN_VALUES_FEEDBACK_HMAC_SHA256.iter().zip(0..) {
368-
let feedback =
369-
Feedback::<HmacSha256, HmacSha512>::new(v.iv.map(GenericArray::from_slice));
479+
struct MockOutput;
480+
481+
impl KeySizeUser for MockOutput {
482+
type KeySize = U64;
483+
}
484+
485+
for (v, i) in KNOWN_VALUES_DOUBLE_PIPELINE_HMAC_SHA256.iter().zip(0..) {
486+
let dbl_pipeline = DoublePipeline::<HmacSha256, MockOutput>::default();
370487
assert_eq!(
371-
feedback.derive(
372-
GenericArray::from_slice(v.key),
373-
v.use_l,
374-
v.use_separator,
375-
v.label,
376-
v.context,
377-
),
378-
Ok(GenericArray::<_, U128>::from_slice(v.expected).clone()),
488+
dbl_pipeline.derive(v.key, v.use_l, v.use_separator, v.label, v.context,),
489+
Ok(GenericArray::<_, _>::from_slice(v.expected).clone()),
379490
"key derivation failed for (index: {i}):\n{v:x?}"
380491
);
381492
}

0 commit comments

Comments
 (0)