AES 实施速度

2024-02-14

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

  1. 什么是一个好的目标,要达到多快的速度才是一个现实的目标。
  2. 为什么我的代码这么慢,我该如何改变它。

到我的代码: 我尝试省略一些函数,以便看看没有它们时代码的速度有多快。 完整代码耗时 72 秒。

  • 没有 Mixcolumns 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;
}

和 xtime 函数:

uint8_t xtime(uint8_t x){
    return (x << 1) ^ (0x11b & -(x >> 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

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

如果我们比较最后一列,您会发现 AES-NI 比 OpenSSL 软件版本快约 6.3 倍。这意味着你的速度比软件版本慢大约 4 倍。

在许多情况下,编译器优化参数也会影响速度。查看你的编译器手册,如果你使用的是 GCC 那么它们是-O[0..3]


关于代码;

如果您查看 OpenSSL 的 AES 代码,您会发现它们使用预先计算的表 https://github.com/openssl/openssl/blob/master/crypto/aes/aes_core.c这是一种非常常见的技术。

The Subytes, Shiftrows and MixColums都变成了查表。速度差异就是这些。并注意表查找很容易受到缓存定时攻击 https://cr.yp.to/antiforgery/cachetiming-20050414.pdf.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AES 实施速度 的相关文章

随机推荐

  • drop_duplicates 在 pandas 中不起作用?

    我的代码的目的是导入 2 个 Excel 文件 比较它们 并将差异打印到新的 Excel 文件中 然而 在连接所有数据并使用drop duplicates函数 代码被控制台接受 但是 当打印到新的 Excel 文件时 当天仍保留重复项 我错
  • iTunes Connect 开发人员拒绝 - 删除不需要的构建/二进制文件

    我将二进制更新上传到新的 iTunesConnect 但尚未提交 我发现了一个错误 并尝试删除现有的二进制文件 找不到方法来做到这一点 然后我提交了审查 但立即被拒绝了 仍然找不到删除它并上传新的方法 如何上传我的新版本 或者如何取消更新并
  • Activity 泄露了 IntentReceiver android.widget.ViewFlipper

    我正在添加一个ViewFlipper从布局资源膨胀为ListView as a Footer 这是我的鳍状肢布局 为简洁起见 省略了详细信息
  • 跟踪 malloc 分配了多少内存

    在快速浏览了 SO 上的相关问题后 我推断没有函数可以检查 malloc 分配给指针的内存量 我正在尝试使用 C 中的简单 char 来复制一些 std string 基本功能 主要是动态大小 并且不想一直调用 realloc 我想我需要跟
  • Android studio gradle与firebase同步错误:响应204:无内容没有内容

    从今天早上开始 我在 android studio 中同步我的 android 项目时遇到了麻烦 当我尝试这样做时 我每次都会遇到相同的错误 部分错误 https i stack imgur com bD3S0 png 所有这些错误都是由同
  • Scala 不可变对象和具有 val 字段的特征

    我想仅使用不可变对象构建我的域模型 但我也想将特征与 val 字段一起使用 并将一些功能移至特征 请看下面的例子 trait Versionable val version 0 def incrementVersion copy versi
  • 为什么我会收到“没有此类方法异常”?

    这是我的代码 看起来没问题 但是当我编译程序时 我得到 No Such method 异常 import java io IOException public class Invoked public static String celeb
  • 如何在 scikit-learn 中正确地将数字特征与文本(词袋)结合起来?

    我正在为网页编写一个分类器 因此我混合了数字特征 并且我还想对文本进行分类 我正在使用词袋方法将文本转换为 大 数值向量 代码最终是这样的 from sklearn feature extraction text import CountV
  • @MustOverride 注释?

    在 NET 中 可以为特定超类中的方法指定 mustoverride 属性 以确保子类重写该特定方法 我想知道是否有人有一个自定义的java注释可以达到相同的效果 本质上 我想要的是推动子类覆盖超类中的方法 该方法本身具有一些必须运行的逻辑
  • 如果违反代码约定规则,如何配置 ReSharper 以使构建失败?

    使用 VS2015 更新 2 ReSharper 2016 1 是否有办法配置 ReSharper 使其在违反代码约定规则时使构建失败 None
  • 有没有办法知道特定程序运行时达到的最大 JVM 调用堆栈深度?

    我今天一直在编写一个递归函数 递归深度取决于输入长度 我想从纯粹兴趣的角度来看 是否有某种方法可以监视 可能在某些 JVM 日志或其他地方 特定程序执行期间的最大调用堆栈深度是多少 经过一番思考 我可以想象一种分析方法来近似计算这个值 但这
  • 用于远程IP(主机)的Java RMI

    我是新手 我无法理解RMI正确 互联网上有大量的教程 但据我所知 它们都是针对本地主机的 服务器和客户端都运行在同一台机器上 我想在任何机器上运行客户端 并且主机将位于一台计算机上 让我们考虑一下IP 11 11 11 11 上1099 但
  • Android:使用 SurfaceView 重新获得焦点

    我目前正在熟悉 Android 尝试 Lunar Lander 示例 我发现 如果您离开应用程序 例如 点击通话按钮 它将破坏底层表面 调用surfaceDestroyed 向后导航 这将触发onWindowVisibilityChange
  • 如何使用 django-rest-framework 测试客户端测试二进制文件上传?

    我有一个 Django 应用程序 其视图接受要上传的文件 使用 Django REST 框架 我对 APIView 进行子类化并实现 post 方法 如下所示 class FileUpload APIView permission clas
  • 如何在 Neo4j 中使用类型层次结构?

    Neo4j 中是否有某种方法可以对类型层次结构进行建模 例如 如果我想构建汽车的类层次结构 我可能有一个 Car 基类型 然后有扩展它的子类 例如 SportCar 等 我希望能够创建 SportCar 的实例 但运行查询来获取所有 Car
  • 在 Cassandra 中存储上次触摸时间的最佳方式

    我将最后一次触摸的时间存储在 Postgres 的 User 表中 但是有许多频繁的更新和足够的争用 我可以看到 3 个相同更新死锁的示例 Cassandra 似乎更适合这个目的 但我应该专门用一个表来实现这个目的吗 我不需要旧的时间戳 只
  • Java 编译器会预先计算文字的总和吗?

    int i 10 20 编译器是否真的会处理这段代码 添加10 20 并且字节码与这行代码相同 int i 30 我在哪里可以读到相关内容 是的 您甚至可以亲自验证 以一个小的 Java 文件为例 public class Main pub
  • 如何从 jenkins Powershell 脚本更新环境变量

    您好尝试从阶段编写的 Powershell 脚本更新 jenkins Env 变量 pipeline agent label master environment def var1 default value def var2 defaul
  • “抄送”c++ istream?

    对于我自己的小解析器框架 我试图定义 类似 以下函数 template
  • AES 实施速度

    我已经编写了 AES 的 C 实现 并尝试使其尽可能快 我刚刚开始编程并接受 IT 培训 到目前为止 我已经实现了约 600 的速度提升 但仍然非常慢 为了将我的 AES 实现与我在 Linux 终端中使用的 openssl speed 命