Skip to content

Commit cbdb9f0

Browse files
authored
serpent: add serpent_no_unroll configuration flag (#476)
1 parent 70fe50a commit cbdb9f0

File tree

7 files changed

+77
-71
lines changed

7 files changed

+77
-71
lines changed

.github/workflows/serpent.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ jobs:
3636
toolchain: ${{ matrix.rust }}
3737
targets: ${{ matrix.target }}
3838
- run: cargo build --no-default-features --release --target ${{ matrix.target }}
39+
- env:
40+
RUSTFLAGS: "-Dwarnings --cfg serpent_no_unroll"
41+
run: cargo build --no-default-features --release --target ${{ matrix.target }}
3942

4043
minimal-versions:
4144
if: false # TODO: temp disabled due to unpublished prerelease dependencies
@@ -60,3 +63,6 @@ jobs:
6063
- run: cargo test --no-default-features
6164
- run: cargo test
6265
- run: cargo test --all-features
66+
- env:
67+
RUSTFLAGS: "-Dwarnings --cfg serpent_no_unroll"
68+
run: cargo test --all-features

serpent/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## 0.6.0 (UNRELEASED)
9+
### Added
10+
- `serpent_no_unroll` configuration flag ([#476])
11+
12+
### Changed
13+
- Improve bitslicing implementation ([#474])
14+
15+
[#474]: https://github.com/RustCrypto/block-ciphers/pull/474
16+
[#476]: https://github.com/RustCrypto/block-ciphers/pull/476
17+
818
## 0.5.1 (2022-02-17)
919
### Fixed
1020
- Minimal versions build ([#303])

serpent/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ zeroize = ["cipher/zeroize"]
2424
[package.metadata.docs.rs]
2525
all-features = true
2626
rustdoc-args = ["--cfg", "docsrs"]
27+
28+
[lints.rust]
29+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(serpent_no_unroll)'] }

serpent/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ architectures.
2626

2727
USE AT YOUR OWN RISK!
2828

29+
## Configuration flags
30+
31+
You can modify crate using the following configuration flags:
32+
33+
- `serpent_no_unroll`: do not unroll rounds loop. Reduces binary size at the cost of slightly lower performance.
34+
35+
The flag can be enabled using RUSTFLAGS environmental variable (e.g. RUSTFLAGS="--cfg serpent_no_unroll") or by modifying .cargo/config.
36+
2937
## Minimum Supported Rust Version
3038

3139
Rust **1.65** or higher.

serpent/src/bitslice.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//!
21
//! Serpent uses 8 4-bit Sboxes which were designed to be implemented using small
32
//! circuits. For each block these Sboxes are applied in a bitsliced fashion.
43
//!
@@ -11,7 +10,6 @@
1110
//!
1211
//! "Speeding Up Serpent", Osvik
1312
//! <https://www.ii.uib.no/~osvik/pub/aes3.pdf>
14-
//!
1513
1614
use crate::Words;
1715

serpent/src/lib.rs

Lines changed: 4 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ use cipher::{
3131
use core::fmt;
3232

3333
mod bitslice;
34+
#[macro_use]
35+
mod unroll;
3436

3537
#[cfg(feature = "zeroize")]
3638
use cipher::zeroize::{Zeroize, ZeroizeOnDrop};
@@ -56,73 +58,6 @@ fn xor(b1: Words, k: Words) -> Words {
5658
res
5759
}
5860

59-
macro_rules! repeat31 {
60-
($i:ident, $body:block) => {
61-
let $i = 0;
62-
$body;
63-
let $i = 1;
64-
$body;
65-
let $i = 2;
66-
$body;
67-
let $i = 3;
68-
$body;
69-
let $i = 4;
70-
$body;
71-
let $i = 5;
72-
$body;
73-
let $i = 6;
74-
$body;
75-
let $i = 7;
76-
$body;
77-
let $i = 8;
78-
$body;
79-
let $i = 9;
80-
$body;
81-
let $i = 10;
82-
$body;
83-
let $i = 11;
84-
$body;
85-
let $i = 12;
86-
$body;
87-
let $i = 13;
88-
$body;
89-
let $i = 14;
90-
$body;
91-
let $i = 15;
92-
$body;
93-
let $i = 16;
94-
$body;
95-
let $i = 17;
96-
$body;
97-
let $i = 18;
98-
$body;
99-
let $i = 19;
100-
$body;
101-
let $i = 20;
102-
$body;
103-
let $i = 21;
104-
$body;
105-
let $i = 22;
106-
$body;
107-
let $i = 23;
108-
$body;
109-
let $i = 24;
110-
$body;
111-
let $i = 25;
112-
$body;
113-
let $i = 26;
114-
$body;
115-
let $i = 27;
116-
$body;
117-
let $i = 28;
118-
$body;
119-
let $i = 29;
120-
$body;
121-
let $i = 30;
122-
$body;
123-
};
124-
}
125-
12661
fn expand_key(source: &[u8], len_bits: usize) -> [u8; 32] {
12762
let mut key = [0u8; 32];
12863
key[..source.len()].copy_from_slice(source);
@@ -208,7 +143,7 @@ impl BlockCipherEncBackend for Serpent {
208143
fn encrypt_block(&self, mut block: InOut<'_, '_, Block<Self>>) {
209144
let mut b: [u32; 4] = read_words(block.get_in().into());
210145

211-
repeat31!(i, {
146+
unroll31!(i, {
212147
let xb = xor(b, self.round_keys[i]);
213148
let s = bitslice::apply_s(i, xb);
214149
b = bitslice::linear_transform(s);
@@ -238,7 +173,7 @@ impl BlockCipherDecBackend for Serpent {
238173
let xb = bitslice::apply_s_inv(ROUNDS - 1, s);
239174
b = xor(xb, self.round_keys[ROUNDS - 1]);
240175

241-
repeat31!(i, {
176+
unroll31!(i, {
242177
let i = 30 - i;
243178
let s = bitslice::linear_transform_inv(b);
244179
let xb = bitslice::apply_s_inv(i, s);

serpent/src/unroll.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#[cfg(not(serpent_no_unroll))]
2+
#[rustfmt::skip]
3+
macro_rules! unroll31 {
4+
($i:ident, $body:block) => {
5+
let $i = 0; $body;
6+
let $i = 1; $body;
7+
let $i = 2; $body;
8+
let $i = 3; $body;
9+
let $i = 4; $body;
10+
let $i = 5; $body;
11+
let $i = 6; $body;
12+
let $i = 7; $body;
13+
let $i = 8; $body;
14+
let $i = 9; $body;
15+
let $i = 10; $body;
16+
let $i = 11; $body;
17+
let $i = 12; $body;
18+
let $i = 13; $body;
19+
let $i = 14; $body;
20+
let $i = 15; $body;
21+
let $i = 16; $body;
22+
let $i = 17; $body;
23+
let $i = 18; $body;
24+
let $i = 19; $body;
25+
let $i = 20; $body;
26+
let $i = 21; $body;
27+
let $i = 22; $body;
28+
let $i = 23; $body;
29+
let $i = 24; $body;
30+
let $i = 25; $body;
31+
let $i = 26; $body;
32+
let $i = 27; $body;
33+
let $i = 28; $body;
34+
let $i = 29; $body;
35+
let $i = 30; $body;
36+
};
37+
}
38+
39+
#[cfg(serpent_no_unroll)]
40+
macro_rules! unroll31 {
41+
($i:ident, $body:block) => {
42+
for $i in 0..31 {
43+
$body;
44+
}
45+
};
46+
}

0 commit comments

Comments
 (0)