C AES实现的速度
我已经写了一个AES的C实现,并试图使它尽可能快(我刚刚开始编程,并接受了培训)。 到目前为止,我已经实现了大约600%的速度提升,但仍然非常缓慢。为了将我的AES实现与我在Linux终端中使用的“openssl speed”命令进行比较。在3秒钟内,此实现对大约36 977 043个块(16字节)进行加密。我的速度大约是它的25倍(36…字节的速度是72秒)。我对两件事很好奇C AES实现的速度,c,performance,encryption,aes,C,Performance,Encryption,Aes,我已经写了一个AES的C实现,并试图使它尽可能快(我刚刚开始编程,并接受了培训)。 到目前为止,我已经实现了大约600%的速度提升,但仍然非常缓慢。为了将我的AES实现与我在Linux终端中使用的“openssl speed”命令进行比较。在3秒钟内,此实现对大约36 977 043个块(16字节)进行加密。我的速度大约是它的25倍(36…字节的速度是72秒)。我对两件事很好奇 好的目标是什么,现实目标的速度有多快 为什么我的代码这么慢,我如何才能改变它 我的代码: 我试着省去了一些函数,看看没
- 如果没有14秒,这是一个大问题
- 不换档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;
}
uint8_t xtime(uint8_t x){
return (x << 1) ^ (0x11b & -(x >> 7));
}
uint32\u t*加密(uint32\u t*expkey,uint32\u t状态[4]){
uint32_t temp[4];
状态[0]=状态[0]^expkey[0];
状态[1]=状态[1]^expkey[1];
状态[2]=状态[2]^expkey[2];
状态[3]=状态[3]^expkey[3];
对于(整数轮=1;轮24&0xFF]>16&0xFF]>8&0xFF]>24)&0xFF>16)&0xFF>8)&0xFF>24)&0xFF>16)&0xFF>8)&0xFF>24)&0xFF>16)&0xFF>8)&0xFF>24)&0xFF>16)&0xFF>8)&0xFF)^xtime3((状态[c]>16)&0xFF)>16)&0xFF>(状态[c]>>16)和0xFF)^xtime3((状态[c]>>8)和0xFF)^(状态[c]>>24)和0xFF)^((状态[c]>>16)和0xFF)^xtime((状态[c]>>8)和0xFF)^xtime3(状态[c]>>24)和0xFF)^(状态[c]>>16)和0xFF)^(状态[c]>>8)和0xFF)^xtime(状态[c]>0xFF”);
}
//添加键
状态[0]=状态[0]^expkey[round*4];
状态[1]=状态[1]^expkey[round*4+1];
状态[2]=状态[2]^expkey[round*4+2];
状态[3]=状态[3]^expkey[round*4+3];
}
//最后子字节
对于(int c=0;c<4;c++){
温度[c]=(sbox[状态[c]>24&0xFF]>16&0xFF]>8&0xFF]>24)和0xFF>16)和0xFF>8)和0xFF>24)和0xFF>16)和0xFF>8)和0xFF>24)和0xFF>16)和0xFF>8)和0xFF>24)和0xFF>16)和0xFF>8)和0xFF>7);
}
我期待所有提示、技巧和改进。OpenSSL在可用的情况下使用AES-NI
openssl speed -evp aes-128-cbc
和产出
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
aes-128-cbc 531549.19k 969335.21k 1045437.10k 1066826.75k 1054665.39k 1052120.41k
由于您没有使用AES-NI,因此需要将其与软件版本进行比较
OPENSSL_ia32cap=”~0x200000200000000″ openssl speed -elapsed -evp aes-128-cbc
如果我们比较上一列,您将看到AES-NI比OpenSSL的软件版本快约6.3倍。这意味着您比软件版本慢约4倍
在许多情况下,编译器优化参数也会影响速度。请查阅编译器手册,如果您使用的是GCC,则它们是-O[0..3]
关于代码; 如果你看一下OpenSSL的AES代码,你会发现他们使用的是一种非常常见的技术
Subytes
、Shiftrows
和MixColums
被转换为表查找。速度上的差异在于这些。而不是表查找容易受到影响。问题寻求关于工作代码的反馈,包括性能改进,在一开始更合适。首先,您确定openssl在用户空间中加密?如果它使用AES-NI指令,可以解释为什么它至少快10倍。@Cheath:为什么你认为用户空间是相关的?AES指令只对数据进行操作;它们没有特权。但是,这并不是你问题的确切答案,这应该在你的脑海中。
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
aes-128-cbc 143802.75k 161369.51k 165049.17k 166054.57k 166262.10k 166461.44k