【发布时间】:2021-02-14 19:22:14
【问题描述】:
我已经编写了 AES 的 C 实现,并试图使其尽可能快(我刚开始编程并接受过 IT 培训)。 到目前为止,我已经实现了大约 600% 的速度提升,但速度仍然非常缓慢。为了将我的 AES 实现与我在 Linux 终端中使用的“openssl speed”命令进行比较。在 3 秒内,此实现加密了大约 36 977 043 个块(16 字节)。我比有点糟糕的慢约 25 倍(36 个字节为 72 秒)。我对两件事感到好奇。
- 什么是一个好的目标,实现一个现实的目标有多快。
- 为什么我的代码这么慢,我该如何改变它。
我的代码: 我试图省略我的一些函数,所以看看没有它们代码会多快。 完整代码耗时 72 秒。
- 没有 Mixcolumns 14 秒 #这是一个大问题
- 没有 Shiftrows 67 秒
- 无子字节 61 秒
我的加密功能:
uint32_t * encrypt(uint32_t * expkey,uint32_t state[4]){
uint32_t temp[4];
state[0] = state[0] ^ expkey[0];
state[1] = state[1] ^ expkey[1];
state[2] = state[2] ^ expkey[2];
state[3] = state[3] ^ expkey[3];
for(int round = 1; round < Nr; round++){
// Subbytes
for (int c = 0; c < 4;c++){
temp[c] = ((sbox[state[c] >> 24 & 0xFF]) << 24 ) + ((sbox[state[c] >> 16 & 0xFF]) << 16 ) + ((sbox[state[c] >> 8 & 0xFF]) << 8 ) + (sbox[state[c] & 0xFF]);
}
// Shiftrows
state[0] = (((temp[0] >> 24) & 0xFF) << 24) + (((temp[1] >> 16) & 0xFF) << 16) + (((temp[2] >> 8) & 0xFF) << 8) + (temp[3] & 0xFF);
state[1] = (((temp[1] >> 24) & 0xFF) << 24) + (((temp[2] >> 16) & 0xFF) << 16) + (((temp[3] >> 8) & 0xFF) << 8) + (temp[0] & 0xFF);
state[2] = (((temp[2] >> 24) & 0xFF) << 24) + (((temp[3] >> 16) & 0xFF) << 16) + (((temp[0] >> 8) & 0xFF) << 8) + (temp[1] & 0xFF);
state[3] = (((temp[3] >> 24) & 0xFF) << 24) + (((temp[0] >> 16) & 0xFF) << 16) + (((temp[1] >> 8) & 0xFF) << 8) + (temp[2] & 0xFF);
// Mixcolums
for (int c = 0; c < 4;c++){
state[c] =
((xtime((state[c] >> 24) & 0xFF) ^ xtime3((state[c] >> 16) & 0xFF) ^ ((state[c] >> 8) & 0xFF) ^ (state[c] & 0xFF)) << 24) +
((((state[c] >> 24) & 0xFF) ^ xtime((state[c] >> 16) & 0xFF) ^ xtime3((state[c] >> 8) & 0xFF) ^ (state[c] & 0xFF)) << 16) +
((((state[c] >> 24) & 0xFF) ^ ((state[c] >> 16) & 0xFF) ^ xtime((state[c] >> 8) & 0xFF) ^ xtime3(state[c] & 0xFF)) << 8 ) +
(xtime3((state[c] >> 24) & 0xFF) ^ ((state[c] >> 16) & 0xFF) ^ ((state[c] >> 8) & 0xFF) ^ xtime(state[c] & 0xFF));
}
// Add Key
state[0] = state[0] ^ expkey[round * 4];
state[1] = state[1] ^ expkey[round * 4 + 1];
state[2] = state[2] ^ expkey[round * 4 + 2];
state[3] = state[3] ^ expkey[round * 4 + 3];
}
// Last Subbytes
for (int c = 0; c < 4;c++){
temp[c] = ((sbox[state[c] >> 24 & 0xFF]) << 24 ) + ((sbox[state[c] >> 16 & 0xFF]) << 16 ) + ((sbox[state[c] >> 8 & 0xFF]) << 8 ) + (sbox[state[c] & 0xFF]);
}
*/
// Last Shiftrow
state[0] = (((temp[0] >> 24) & 0xFF) << 24) + (((temp[1] >> 16) & 0xFF) << 16) + (((temp[2] >> 8) & 0xFF) << 8) + (temp[3] & 0xFF);
state[1] = (((temp[1] >> 24) & 0xFF) << 24) + (((temp[2] >> 16) & 0xFF) << 16) + (((temp[3] >> 8) & 0xFF) << 8) + (temp[0] & 0xFF);
state[2] = (((temp[2] >> 24) & 0xFF) << 24) + (((temp[3] >> 16) & 0xFF) << 16) + (((temp[0] >> 8) & 0xFF) << 8) + (temp[1] & 0xFF);
state[3] = (((temp[3] >> 24) & 0xFF) << 24) + (((temp[0] >> 16) & 0xFF) << 16) + (((temp[1] >> 8) & 0xFF) << 8) + (temp[2] & 0xFF);
// Last Add Key
state[0] = state[0] ^ expkey[Nr * 4];
state[1] = state[1] ^ expkey[Nr * 4 + 1];
state[2] = state[2] ^ expkey[Nr * 4 + 2];
state[3] = state[3] ^ expkey[Nr * 4 + 3];
return state;
}
还有xtime函数:
uint8_t xtime(uint8_t x){
return (x << 1) ^ (0x11b & -(x >> 7));
}
我期待所有提示技巧和改进。
【问题讨论】:
-
寻求有关工作代码的反馈(包括性能改进)的问题将更适合Code Review。
-
首先,你确定openssl是在用户空间加密的吗?如果它使用 AES-NI 指令,就可以解释为什么它至少快 10 倍。
-
@Cheatah:为什么你认为用户空间是相关的? AES 指令只对数据进行操作;他们没有特权。
标签: c performance encryption aes