aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs128
1 files changed, 96 insertions, 32 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 205f98b..6407cb5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -480,19 +480,7 @@ fn cipher_aez_tiny(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
}
}
-fn cipher_aez_core(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
- assert!(message.len() >= 32);
- let delta = aez_hash(aez, tweaks);
- let mut blocks = BlockAccessor::new(message);
- let (m_u, m_v, m_x, m_y, d) = (
- blocks.m_u(),
- blocks.m_v(),
- blocks.m_x(),
- blocks.m_y(),
- blocks.m_uv_len(),
- );
- let len_v = d.saturating_sub(128);
-
+fn pass_one(aez: &Aez, blocks: &mut BlockAccessor) -> Block {
let mut x = Block::null();
let mut e1_eval = E::new(1, 0, aez);
let e0_eval = E::new(0, 0, aez);
@@ -510,6 +498,48 @@ fn cipher_aez_core(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
x = x ^ xi;
}
+ x
+}
+
+fn pass_two(aez: &Aez, blocks: &mut BlockAccessor, s: Block) -> Block {
+ let mut y = Block::null();
+ let e2_eval = E::new(2, 0, aez);
+ let mut e1_eval = E::new(1, 0, aez);
+ let e0_eval = E::new(0, 0, aez);
+
+ for ((raw_wi, raw_xi), s_) in blocks.pairs_mut().zip(e2_eval.evals_for(s)) {
+ e1_eval.advance();
+ let wi = Block::from(*raw_wi);
+ let xi = Block::from(*raw_xi);
+ let yi = wi ^ s_;
+ let zi = xi ^ s_;
+ let ci_ = yi ^ e0_eval.eval(zi);
+ let ci = zi ^ e1_eval.eval(ci_);
+
+ ci.write_to(raw_wi);
+ ci_.write_to(raw_xi);
+
+ y = y ^ yi;
+ }
+
+ y
+}
+
+fn cipher_aez_core(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
+ assert!(message.len() >= 32);
+ let delta = aez_hash(aez, tweaks);
+ let mut blocks = BlockAccessor::new(message);
+ let (m_u, m_v, m_x, m_y, d) = (
+ blocks.m_u(),
+ blocks.m_v(),
+ blocks.m_x(),
+ blocks.m_y(),
+ blocks.m_uv_len(),
+ );
+ let len_v = d.saturating_sub(128);
+
+ let mut x = pass_one(aez, &mut blocks);
+
match d {
0 => (),
_ if d <= 127 => {
@@ -534,25 +564,7 @@ fn cipher_aez_core(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) {
}
let s = s_x ^ s_y;
- let mut y = Block::null();
- let mut e2_eval = E::new(2, 0, aez);
- let mut e1_eval = E::new(1, 0, aez);
- for (raw_wi, raw_xi) in blocks.pairs_mut() {
- e2_eval.advance();
- e1_eval.advance();
- let wi = Block::from(*raw_wi);
- let xi = Block::from(*raw_xi);
- let s_ = e2_eval.eval(s);
- let yi = wi ^ s_;
- let zi = xi ^ s_;
- let ci_ = yi ^ e0_eval.eval(zi);
- let ci = zi ^ e1_eval.eval(ci_);
-
- ci.write_to(raw_wi);
- ci_.write_to(raw_xi);
-
- y = y ^ yi;
- }
+ let mut y = pass_two(aez, &mut blocks, s);
let mut c_u = Block::default();
let mut c_v = Block::default();
@@ -678,6 +690,10 @@ impl<'a> E<'a> {
self.aez.aes.aes4(block ^ delta)
}
+ fn evals_for(self, block: Block) -> impl Iterator<Item=Block> {
+ Eiter::new(self, block)
+ }
+
/// Advance this computation by going from i to i+1.
///
/// Afterwards, this computation will represent E_K^{j, i+1}
@@ -692,6 +708,54 @@ impl<'a> E<'a> {
}
}
+struct Eiter<'a> {
+ e: E<'a>,
+ value: Block,
+ blocks: [Block; 8],
+ len: usize,
+}
+
+impl<'a> Eiter<'a> {
+ fn new(e: E<'a>, value: Block) -> Self {
+ assert_eq!(e.i, 0);
+ Eiter {
+ e,
+ value,
+ blocks: [Default::default(); 8],
+ len: 0,
+ }
+ }
+
+ fn refill(&mut self) {
+ self.e.ki_p_i = self.e.ki_p_i * 2;
+ let pre_xored = self.value ^ self.e.kj_t_j ^ self.e.ki_p_i;
+ self.blocks = [
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[1]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[2]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[3]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[4]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[5]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[6]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[7]),
+ self.e.aez.aes.aes4(pre_xored ^ self.e.aez.key_l_multiples[0]),
+ ];
+ self.len = 8;
+ }
+}
+
+impl<'a> Iterator for Eiter<'a> {
+ type Item = Block;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.len == 0 {
+ self.refill();
+ }
+ let result = Some(self.blocks[8 - self.len]);
+ self.len -= 1;
+ result
+ }
+}
+
/// Shorthand to get E_K^{j,i}(block)
fn e(j: i32, i: u32, aez: &Aez, block: Block) -> Block {
if j == -1 {