C AES实现的速度

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秒)。我对两件事很好奇 好的目标是什么,现实目标的速度有多快 为什么我的代码这么慢,我如何才能改变它 我的代码: 我试着省去了一些函数,看看没

我已经写了一个AES的C实现,并试图使它尽可能快(我刚刚开始编程,并接受了培训)。 到目前为止,我已经实现了大约600%的速度提升,但仍然非常缓慢。为了将我的AES实现与我在Linux终端中使用的“openssl speed”命令进行比较。在3秒钟内,此实现对大约36 977 043个块(16字节)进行加密。我的速度大约是它的25倍(36…字节的速度是72秒)。我对两件事很好奇

  • 好的目标是什么,现实目标的速度有多快
  • 为什么我的代码这么慢,我如何才能改变它
  • 我的代码: 我试着省去了一些函数,看看没有它们代码会快多少。 完整的代码花了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