diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 88 |
1 files changed, 74 insertions, 14 deletions
@@ -481,6 +481,54 @@ fn cipher_aez_tiny(mode: Mode, aez: &Aez, tweaks: Tweak, message: &mut [u8]) { } } +macro_rules! unroll_pairs { + ( + $accessor:expr; + setup_unrolled => $setup_unrolled:block; + setup_single => $setup_single:block; + roll ($left:ident, $right:ident) => $roll:block; + ) => { + for (left, right) in $accessor.pairs_8_mut() { + $setup_unrolled; + + let [l0, l1, l2, l3, l4, l5, l6, l7] = left; + let [r0, r1, r2, r3, r4, r5, r6, r7] = right; + + let $left = l0; + let $right = r0; + $roll; + let $left = l1; + let $right = r1; + $roll; + let $left = l2; + let $right = r2; + $roll; + let $left = l3; + let $right = r3; + $roll; + let $left = l4; + let $right = r4; + $roll; + let $left = l5; + let $right = r5; + $roll; + let $left = l6; + let $right = r6; + $roll; + let $left = l7; + let $right = r7; + $roll; + } + + for (left, right) in $accessor.suffix_8_mut() { + let $left = left; + let $right = right; + $setup_single; + $roll; + } + }; +} + fn pass_one(aez: &Aez, blocks: &mut BlockAccessor) -> Block { let mut x = Block::null(); let mut e1_eval = E::new(1, 0, aez); @@ -507,20 +555,32 @@ fn pass_two(aez: &Aez, blocks: &mut BlockAccessor, s: Block) -> Block { 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); + let mut evals_for_s = e2_eval.evals_for(s); - 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; + unroll_pairs! { blocks; + setup_unrolled => { + evals_for_s.refill(); + }; + setup_single => { + if evals_for_s.len == 0 { + evals_for_s.refill(); + } + }; + roll (raw_wi, raw_xi) => { + e1_eval.advance(); + let wi = Block::from(*raw_wi); + let xi = Block::from(*raw_xi); + let yi = wi ^ evals_for_s.blocks[8 - evals_for_s.len]; + let zi = xi ^ evals_for_s.blocks[8 - evals_for_s.len]; + 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; + evals_for_s.len -= 1; + }; } y @@ -692,7 +752,7 @@ impl<'a> E<'a> { self.aez.aes.aes4(block ^ delta) } - fn evals_for(self, block: Block) -> impl Iterator<Item = Block> { + fn evals_for(self, block: Block) -> Eiter<'a> { Eiter::new(self, block) } |