7次发布

0.3.1 2024年8月11日
0.3.0 2024年8月10日
0.2.0 2024年8月9日
0.1.3 2024年8月4日

#198 in 算法

Download history 211/week @ 2024-08-04 131/week @ 2024-08-11

342 个月下载量

Apache-2.0

195KB
4K SLoC

基于AES的伪随机数生成器

CI Crate API

该包实现了使用AES分组密码在计数器(CTR)模式下进行的伪随机数生成器(PRNG)。

特性

  • 基于成熟的加密原则。
  • 针对低延迟和高吞吐量进行了优化。
  • 通过严格的统计测试(practrandTESTu01's Big Crush)。
  • 提供RandomJump特性以实现常见功能。
  • 支持rand_core包提供的特性。
  • getrandom包提供了安全初始化支持。
  • 支持no_std。

包特性

  • getrandom:基于getrandom包提供安全种子功能。
  • rand_core:实现了rand_core包提供的特性。
  • tls:提供基于线程局部存储的实用函数,以便轻松生成随机数。

禁用默认特性时,该包与no_std兼容。

用法

将以下内容添加到您的Cargo.toml

[dependencies]
rand_aes = "0.1"

然后您可以像这样使用它

use rand_aes::{Random, Aes128Ctr64};

fn main() {
    let prng = Aes128Ctr64::from_entropy();
    let random_u64 = prng.u64;
}

计数器实现细节

使用64位或128位计数器,可在初始化时随机播种。在64位计数器的情况下,我们使用128位变量,并在初始化时对该变量进行种子。较高64位在此情况下作为nonce使用。计数器在溢出时回绕,确保连续运行。

安全提示

虽然基于成熟的加密原语,但此PRNG不打算用于密钥生成或其他敏感加密操作,因为不提供安全、自动重新播种。我们通过运行具有减少轮次的版本来测试其统计特性,并与practrandTESTu01's Big Crush进行对比。仅3轮AES加密的版本通过至少16 TB的practrand测试。要成功清除TESTu01's Big Crush,至少需要5轮。AES-128使用10轮,AES-256使用14轮。

支持的架构

当没有提供硬件加速的AES时,我们提供AES的软件实现。我们为以下架构提供硬件加速版本:

  • aarch64: 自Cortex-A53(2012)开始支持。
  • riscv64: 使用向量加密扩展进行实验性支持。
  • x86_64, x86: 自Intel的Westmere(2010)和AMD的Bulldozer(2011)开始支持。

实验性RISC-V支持

RISC-V有两个AES扩展,标量(zkn)和向量加密扩展(zvkn)。目前,没有任何基于硬件的CPU支持它们。也不清楚哪个平台会优先支持哪个。由于这个crate主要针对应用级架构(与嵌入式相对),我们认为提供向量加密实现是最安全的。由于没有向量加密扩展的内联原语,我们提供了手写的ASM实现。由于目前无法发现对向量加密扩展的支持(截至2024年8月),您需要在编译时选择所需的target功能和一个实验性crate功能。生成的可执行文件只能在具有向量加密扩展的系统中运行。

.cargo/config.toml中激活向量扩展和向量加密扩展的目标功能。例如:

[target.'cfg(target_arch="riscv64")']
rustflags = ["-C", "target-feature=+v,+zvkn"]

您还需要选择experimental_riscv crate功能。这个功能是实验性的,将来很可能会成为绝对功能(一旦有了内联原语和运行时发现)。

最佳性能

我们为所有支持的平台提供硬件加速AES指令集的运行时检测。如果执行CPU不支持硬件加速AES,则提供软件回退。但我们强烈建议在编译时启用特定的目标功能,因为AES指令集在现代桌面CPU上至少可用10年。启用目标功能使编译器能够更积极地进行内联,并提供更好的性能。运行时检测不支持在no_std中。

使用以下目标功能以获得最佳性能:

  • aarch64: "aes"(使用加密扩展)
  • riscv64: "v"和"zvkn"(使用向量和向量加密扩展)
  • x86: "sse2"和"aes"(使用AES-NI)
  • x86_64: "aes"(使用AES-NI)

示例在.cargo/config.toml

[target.'cfg(target_arch="aarch64")']
rustflags = ["-C", "target-feature=+aes"]

[target.'cfg(target_arch="riscv64")']
rustflags = ["-C", "target-feature=+v,+zvkn"]

[target.'cfg(target_arch="x86")']
rustflags = ["-C", "target-feature=+sse2,+aes"]

[target.'cfg(target_arch="x86_64")']
rustflags = ["-C", "target-feature=+aes"]

基准测试

以下基准测试使用版本v0.1.0和启用的硬件AES目标功能进行。

对于aarch64笔记本电脑:M1 Pro(14" MacBook Pro,2021)

Latency/TLS             time:   [1.1510 ns 1.1522 ns 1.1536 ns]
Latency/Aes128Ctr64     time:   [1.1830 ns 1.1895 ns 1.1964 ns]
Latency/Aes128Ctr128    time:   [1.3711 ns 1.3747 ns 1.3792 ns]
Latency/Aes256Ctr64     time:   [1.8304 ns 1.8478 ns 1.8678 ns]
Latency/Aes256Ctr128    time:   [2.0468 ns 2.0474 ns 2.0480 ns]
Latency/ChaCha8         time:   [5.9017 ns 5.9146 ns 5.9327 ns]
Latency/ChaCha12        time:   [8.3993 ns 8.4023 ns 8.4063 ns]
Latency/ChaCha20        time:   [13.577 ns 13.721 ns 13.917 ns]
Latency/Lcg128Xsl64     time:   [1.6307 ns 1.6323 ns 1.6344 ns]
Latency/Mcg128Xsl64     time:   [1.2409 ns 1.2417 ns 1.2427 ns]

Throughput/TLS          thrpt:  [12.655 GiB/s 12.657 GiB/s 12.659 GiB/s]
Throughput/Aes128Ctr64  thrpt:  [12.601 GiB/s 12.625 GiB/s 12.644 GiB/s]
Throughput/Aes128Ct128  thrpt:  [11.315 GiB/s 11.349 GiB/s 11.380 GiB/s]
Throughput/Aes256Ctr64  thrpt:  [8.4748 GiB/s 8.4896 GiB/s 8.5014 GiB/s]
Throughput/Aes256Ct128  thrpt:  [7.4943 GiB/s 7.5061 GiB/s 7.5158 GiB/s]
Throughput/ChaCha8      thrpt:  [1.3391 GiB/s 1.3402 GiB/s 1.3410 GiB/s]
Throughput/ChaCha12     thrpt:  [935.03 MiB/s 938.98 MiB/s 942.22 MiB/s]
Throughput/ChaCha20     thrpt:  [578.33 MiB/s 580.03 MiB/s 581.44 MiB/s]
Throughput/Lcg128Xsl64  thrpt:  [4.5148 GiB/s 4.5335 GiB/s 4.5529 GiB/s]
Throughput/Mcg128Xsl64  thrpt:  [5.9140 GiB/s 5.9424 GiB/s 5.9664 GiB/s]

对于x86_64台式机:AMD Ryzen 9 5950X

Latency/TLS             time:   [1.0577 ns 1.0592 ns 1.0616 ns]
Latency/Aes128Ctr64     time:   [1.0680 ns 1.0695 ns 1.0712 ns]
Latency/Aes128Ctr128    time:   [1.1573 ns 1.1582 ns 1.1592 ns]
Latency/Aes256Ctr64     time:   [1.6956 ns 1.7074 ns 1.7252 ns]
Latency/Aes256Ctr128    time:   [1.7394 ns 1.7410 ns 1.7427 ns]
Latency/ChaCha8         time:   [1.4317 ns 1.4338 ns 1.4363 ns]
Latency/ChaCha12        time:   [1.9144 ns 1.9162 ns 1.9182 ns]
Latency/ChaCha20        time:   [2.9326 ns 2.9349 ns 2.9375 ns]
Latency/Lcg128Xsl64     time:   [1.1708 ns 1.1717 ns 1.1727 ns]
Latency/Mcg128Xsl64     time:   [863.11 ps 863.58 ps 864.11 ps]

Throughput/TLS          thrpt:  [14.118 GiB/s 14.130 GiB/s 14.141 GiB/s]
Throughput/Aes128Ctr64  thrpt:  [14.012 GiB/s 14.034 GiB/s 14.054 GiB/s]
Throughput/Aes128Ct128  thrpt:  [13.347 GiB/s 13.357 GiB/s 13.367 GiB/s]
Throughput/Aes256Ctr64  thrpt:  [8.8344 GiB/s 8.8416 GiB/s 8.8483 GiB/s]
Throughput/Aes256Ct128  thrpt:  [7.7617 GiB/s 7.7838 GiB/s 7.8044 GiB/s]
Throughput/ChaCha8      thrpt:  [6.6074 GiB/s 6.6142 GiB/s 6.6203 GiB/s]
Throughput/ChaCha12     thrpt:  [4.5944 GiB/s 4.5981 GiB/s 4.6015 GiB/s]
Throughput/ChaCha20     thrpt:  [2.8697 GiB/s 2.8727 GiB/s 2.8753 GiB/s]
Throughput/Lcg128Xsl64  thrpt:  [5.2476 GiB/s 5.3558 GiB/s 5.4613 GiB/s]
Throughput/Mcg128Xsl64  thrpt:  [7.6245 GiB/s 7.7582 GiB/s 7.8882 GiB/s]

对于aarch64单板计算机:ARM Cortex-A73(Odroid N2+)

Latency/TLS             time:   [7.0580 ns 7.0992 ns 7.1399 ns]
Latency/Aes128Ctr64     time:   [7.4022 ns 7.4125 ns 7.4233 ns]
Latency/Aes128Ctr128    time:   [6.3027 ns 6.3144 ns 6.3275 ns]
Latency/Aes256Ctr64     time:   [10.006 ns 10.007 ns 10.007 ns]
Latency/Aes256Ctr128    time:   [9.1727 ns 9.1730 ns 9.1735 ns]
Latency/ChaCha8         time:   [25.923 ns 25.928 ns 25.934 ns]
Latency/ChaCha12        time:   [36.375 ns 36.379 ns 36.384 ns]
Latency/ChaCha20        time:   [57.162 ns 57.168 ns 57.174 ns]
Latency/Lcg128Xsl64     time:   [6.2690 ns 6.2725 ns 6.2765 ns]
Latency/Mcg128Xsl64     time:   [6.2628 ns 6.2649 ns 6.2674 ns]

Throughput/TLS          thrpt:  [2.1681 GiB/s 2.1689 GiB/s 2.1697 GiB/s]
Throughput/Aes128Ctr64  thrpt:  [2.1290 GiB/s 2.1365 GiB/s 2.1440 GiB/s]
Throughput/Aes128Ct128  thrpt:  [2.3520 GiB/s 2.3621 GiB/s 2.3720 GiB/s]
Throughput/Aes256Ctr64  thrpt:  [1.5376 GiB/s 1.5402 GiB/s 1.5427 GiB/s]
Throughput/Aes256Ct128  thrpt:  [1.7468 GiB/s 1.7499 GiB/s 1.7530 GiB/s]
Throughput/ChaCha8      thrpt:  [315.66 MiB/s 315.77 MiB/s 315.88 MiB/s]
Throughput/ChaCha12     thrpt:  [220.51 MiB/s 220.58 MiB/s 220.65 MiB/s]
Throughput/ChaCha20     thrpt:  [137.55 MiB/s 137.59 MiB/s 137.64 MiB/s]
Throughput/Lcg128Xsl64  thrpt:  [1.1512 GiB/s 1.1512 GiB/s 1.1513 GiB/s]
Throughput/Mcg128Xsl64  thrpt:  [1.1766 GiB/s 1.1766 GiB/s 1.1767 GiB/s]

致谢

AES-128和AES-256的基于软件的固定切片实现是RustCrypto团队编写的aes crate的副本。原始C实现作者是Alexandre Adomnicai。

我们不直接使用AES crate,仅仅是因为它内联得不是很好,而且我们可以通过这种方式提供更好的内部可变性(因为我们优化了在编译时硬件基于AES可用的情况下的快速路径)。

许可

Apache License, Version 2.0下许可。

依赖

~88-260KB