当前位置: 首页 > news >正文

C++ 通过AES-NI指令集高级硬件加速实现AES-128-CFB算法。

本文代码关联文章:

C++ 通过AES-NI指令集高级硬件加速实现AES-256-CFB算法。-CSDN博客

高性能AES_128_CFB(AES密码反馈模式)实现,基于INTEL/AMD处理器AES-NI指令集结合SSE指令集实现。

AES_128_CFB、AES_256_CFB之间区别只有 “密钥扩展函数” 轮次及立即数常数的不同。

AES_128_CFB 密钥扩展函数立即数轮常数(为10个、AES_256_CFB为14个)

以下列出128的轮次常数:

第1轮: 0x01
第2轮: 0x02
第3轮: 0x04
第4轮: 0x08
第5轮: 0x10
第6轮: 0x20
第7轮: 0x40
第8轮: 0x80
第9轮: 0x1B
第10轮: 0x36

以下列出256的轮次常数:(有14轮,未列出的立即数常数为:0)

第1轮:0x01
第3轮:0x02
第5轮:0x04
第7轮:0x08
第9轮:0x10
第11轮:0x20
第13轮:0x40

 AES-256 的 14 轮加密,轮常数的完整序列为:

0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00

AES两者实现的效率对比:

运行输出:

root@liulilte:~/dev/aes_test/bin# ./aes_test
=== AES-128-CFB 实现验证 ====== 加密结果对比 ===
自定义实现加密 (显示前35字节): 21 a1 8c b4 05 57 24 71 9d 9e 9a b1 42 8c e8 19 85 bc c1 0a 7d 79 3a 30 eb dd da 6c f5 b5 ba ac 36 da be 
OpenSSL 加密    (显示前35字节): 21 a1 8c b4 05 57 24 71 9d 9e 9a b1 42 8c e8 19 85 bc c1 0a 7d 79 3a 30 eb dd da 6c f5 b5 ba ac 36 da be 
加密结果匹配: 是测试通过: 所有结果匹配!=== 性能测试 (10万次加密) ===
数据长度: 346 字节
总数据量: 33.00 MB自定义实现:总时间: 0.01478 秒平均时间: 0.00015 毫秒/次吞吐量: 2231.95 MB/sOpenSSL 实现:总时间: 0.05505 秒平均时间: 0.00055 毫秒/次吞吐量: 599.38 MB/s性能比较:自定义实现比OpenSSL快 73.15%吞吐量比率: 3.72x

AES_128_CFB的源代码实现:

#include <wmmintrin.h>   // AES 指令集
#include <emmintrin.h>   // SSE2 指令集
#include <string.h>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <algorithm>     // std::min
#include <openssl/evp.h> // OpenSSL 加密
#include <vector>        // 用于存储测试数据// AES-128 密钥扩展 (生成11个轮密钥)
void aes128_key_expansion(const uint8_t *key, __m128i *round_key) {round_key[0] = _mm_loadu_si128((const __m128i*)key);// 展开循环,为每轮提供正确的立即数轮常数__m128i temp = _mm_aeskeygenassist_si128(round_key[0], 0x01);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[1] = _mm_xor_si128(round_key[0], _mm_slli_si128(round_key[0], 4));round_key[1] = _mm_xor_si128(round_key[1], _mm_slli_si128(round_key[1], 8));round_key[1] = _mm_xor_si128(round_key[1], temp);temp = _mm_aeskeygenassist_si128(round_key[1], 0x02);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[2] = _mm_xor_si128(round_key[1], _mm_slli_si128(round_key[1], 4));round_key[2] = _mm_xor_si128(round_key[2], _mm_slli_si128(round_key[2], 8));round_key[2] = _mm_xor_si128(round_key[2], temp);temp = _mm_aeskeygenassist_si128(round_key[2], 0x04);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[3] = _mm_xor_si128(round_key[2], _mm_slli_si128(round_key[2], 4));round_key[3] = _mm_xor_si128(round_key[3], _mm_slli_si128(round_key[3], 8));round_key[3] = _mm_xor_si128(round_key[3], temp);temp = _mm_aeskeygenassist_si128(round_key[3], 0x08);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[4] = _mm_xor_si128(round_key[3], _mm_slli_si128(round_key[3], 4));round_key[4] = _mm_xor_si128(round_key[4], _mm_slli_si128(round_key[4], 8));round_key[4] = _mm_xor_si128(round_key[4], temp);temp = _mm_aeskeygenassist_si128(round_key[4], 0x10);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[5] = _mm_xor_si128(round_key[4], _mm_slli_si128(round_key[4], 4));round_key[5] = _mm_xor_si128(round_key[5], _mm_slli_si128(round_key[5], 8));round_key[5] = _mm_xor_si128(round_key[5], temp);temp = _mm_aeskeygenassist_si128(round_key[5], 0x20);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[6] = _mm_xor_si128(round_key[5], _mm_slli_si128(round_key[5], 4));round_key[6] = _mm_xor_si128(round_key[6], _mm_slli_si128(round_key[6], 8));round_key[6] = _mm_xor_si128(round_key[6], temp);temp = _mm_aeskeygenassist_si128(round_key[6], 0x40);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[7] = _mm_xor_si128(round_key[6], _mm_slli_si128(round_key[6], 4));round_key[7] = _mm_xor_si128(round_key[7], _mm_slli_si128(round_key[7], 8));round_key[7] = _mm_xor_si128(round_key[7], temp);temp = _mm_aeskeygenassist_si128(round_key[7], 0x80);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[8] = _mm_xor_si128(round_key[7], _mm_slli_si128(round_key[7], 4));round_key[8] = _mm_xor_si128(round_key[8], _mm_slli_si128(round_key[8], 8));round_key[8] = _mm_xor_si128(round_key[8], temp);temp = _mm_aeskeygenassist_si128(round_key[8], 0x1B);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[9] = _mm_xor_si128(round_key[8], _mm_slli_si128(round_key[8], 4));round_key[9] = _mm_xor_si128(round_key[9], _mm_slli_si128(round_key[9], 8));round_key[9] = _mm_xor_si128(round_key[9], temp);temp = _mm_aeskeygenassist_si128(round_key[9], 0x36);temp = _mm_shuffle_epi32(temp, 0xFF);round_key[10] = _mm_xor_si128(round_key[9], _mm_slli_si128(round_key[9], 4));round_key[10] = _mm_xor_si128(round_key[10], _mm_slli_si128(round_key[10], 8));round_key[10] = _mm_xor_si128(round_key[10], temp);
}// AES-128 加密单个128位块
__m128i aes128_encrypt_block(__m128i block, const __m128i *round_key) {block = _mm_xor_si128(block, round_key[0]); // 初始轮密钥加// 执行9轮完整AES轮函数for (int i = 1; i < 10; i++) {block = _mm_aesenc_si128(block, round_key[i]);}// 最后一轮(无MixColumns)block = _mm_aesenclast_si128(block, round_key[10]);return block;
}// AES-128-CFB 加密
void aes128_cfb_encrypt(uint8_t *ciphertext, const uint8_t *plaintext, size_t len,const uint8_t *iv, const __m128i *round_key) {__m128i feedback = _mm_loadu_si128((const __m128i*)iv); // 初始化反馈寄存器size_t blocks = len / 16;    // 完整块数量size_t remaining = len % 16; // 剩余字节数// 处理完整块for (size_t i = 0; i < blocks; i++) {// 生成密钥流__m128i keystream = aes128_encrypt_block(feedback, round_key);// 加载当前明文块__m128i plain_block = _mm_loadu_si128((const __m128i*)(plaintext + i * 16));// 异或生成密文块__m128i cipher_block = _mm_xor_si128(plain_block, keystream);// 存储密文块_mm_storeu_si128((__m128i*)(ciphertext + i * 16), cipher_block);// 更新反馈寄存器(使用新生成的密文)feedback = cipher_block;}// 处理部分块if (remaining > 0) {// 生成部分密钥流__m128i keystream = aes128_encrypt_block(feedback, round_key);const uint8_t* src = plaintext + blocks * 16;uint8_t* dst = ciphertext + blocks * 16;// 逐字节异或处理剩余数据for (size_t i = 0; i < remaining; i++) {dst[i] = src[i] ^ ((uint8_t*)&keystream)[i];}}
}// AES-128-CFB 解密
void aes128_cfb_decrypt(uint8_t *plaintext, const uint8_t *ciphertext, size_t len,const uint8_t *iv, const __m128i *round_key) {__m128i feedback = _mm_loadu_si128((const __m128i*)iv); // 初始化反馈寄存器size_t blocks = len / 16;    // 完整块数量size_t remaining = len % 16; // 剩余字节数// 处理完整块for (size_t i = 0; i < blocks; i++) {// 生成密钥流__m128i keystream = aes128_encrypt_block(feedback, round_key);// 加载当前密文块__m128i cipher_block = _mm_loadu_si128((const __m128i*)(ciphertext + i * 16));// 异或生成明文块__m128i plain_block = _mm_xor_si128(cipher_block, keystream);// 存储明文块_mm_storeu_si128((__m128i*)(plaintext + i * 16), plain_block);// 更新反馈寄存器(使用当前密文)feedback = cipher_block;}// 处理部分块if (remaining > 0) {// 生成部分密钥流__m128i keystream = aes128_encrypt_block(feedback, round_key);const uint8_t* src = ciphertext + blocks * 16;uint8_t* dst = plaintext + blocks * 16;// 逐字节异或处理剩余数据for (size_t i = 0; i < remaining; i++) {dst[i] = src[i] ^ ((uint8_t*)&keystream)[i];}}
}// 打印十六进制数据
void print_hex(const char* label, const uint8_t* data, size_t len, size_t max_display = 128) {std::cout << label << " (显示前" << std::min(len, max_display) << "字节): ";size_t display_len = std::min(len, max_display);for (size_t i = 0; i < display_len; i++) {std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[i]) << " ";}std::cout << (len > max_display ? "..." : "") << std::dec << "\n";
}// 使用OpenSSL进行AES-128-CFB加密
bool openssl_aes128_cfb_encrypt(uint8_t *ciphertext, const uint8_t *plaintext, size_t len,const uint8_t *key, const uint8_t *iv) {EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();if (!ctx) return false;// 初始化加密上下文if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cfb128(), NULL, key, iv)) {EVP_CIPHER_CTX_free(ctx);return false;}// 禁用填充 (CFB模式不需要填充)EVP_CIPHER_CTX_set_padding(ctx, 0);int out_len;// 执行加密if (1 != EVP_EncryptUpdate(ctx, ciphertext, &out_len, plaintext, len)) {EVP_CIPHER_CTX_free(ctx);return false;}// 结束加密流int final_len;if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + out_len, &final_len)) {EVP_CIPHER_CTX_free(ctx);return false;}EVP_CIPHER_CTX_free(ctx);return true;
}// 验证实现正确性(包括与OpenSSL对比)
bool test_aes128_cfb() {// 测试向量 (128位密钥)uint8_t key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};uint8_t iv[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};const char* plaintext = "Hello, AES-128-CFB! This is a test.";size_t len = strlen(plaintext);// 扩展密钥存储 (11轮)__m128i round_key[11];aes128_key_expansion(key, round_key);// 分配内存uint8_t* ciphertext = new uint8_t[len];uint8_t* openssl_ciphertext = new uint8_t[len];uint8_t* decrypted = new uint8_t[len + 1];// 使用自定义实现加密aes128_cfb_encrypt(ciphertext, (const uint8_t*)plaintext, len, iv, round_key);// 使用OpenSSL加密if (!openssl_aes128_cfb_encrypt(openssl_ciphertext, (const uint8_t*)plaintext, len, key, iv)) {std::cerr << "OpenSSL加密失败!\n";delete[] ciphertext;delete[] openssl_ciphertext;delete[] decrypted;return false;}// 对比加密结果bool encryption_match = memcmp(ciphertext, openssl_ciphertext, len) == 0;std::cout << "\n=== 加密结果对比 ===\n";print_hex("自定义实现加密", ciphertext, len);print_hex("OpenSSL 加密   ", openssl_ciphertext, len);std::cout << "加密结果匹配: " << (encryption_match ? "是" : "否") << "\n";// 使用自定义实现解密aes128_cfb_decrypt(decrypted, ciphertext, len, iv, round_key);decrypted[len] = '\0'; // 添加终止符// 验证解密结果bool decryption_match = memcmp(plaintext, decrypted, len) == 0;if (!encryption_match || !decryption_match) {std::cerr << "\n测试失败!\n";if (!encryption_match) {std::cerr << "错误: 加密结果与OpenSSL不一致!\n";}if (!decryption_match) {std::cerr << "错误: 解密结果与原始文本不匹配!\n";std::cerr << "原始文本: " << plaintext << "\n";std::cerr << "解密文本: " << decrypted << "\n";}// 打印详细数据print_hex("原始数据", (const uint8_t*)plaintext, len);print_hex("解密数据", decrypted, len);delete[] ciphertext;delete[] openssl_ciphertext;delete[] decrypted;return false;}delete[] ciphertext;delete[] openssl_ciphertext;delete[] decrypted;std::cout << "\n测试通过: 所有结果匹配!\n";return true;
}// 性能测试函数
void performance_test(const uint8_t* key, const uint8_t* iv, const uint8_t* plaintext, size_t len,const __m128i* round_key) {const int TEST_ITERATIONS = 100000; // 10万次测试// 准备输入输出缓冲区std::vector<uint8_t> input_buffer(plaintext, plaintext + len);std::vector<uint8_t> output_buffer(len);// 预热缓存(运行几次以避免冷启动影响)for (int i = 0; i < 10; i++) {aes128_cfb_encrypt(output_buffer.data(), input_buffer.data(), len, iv, round_key);openssl_aes128_cfb_encrypt(output_buffer.data(), input_buffer.data(), len, key, iv);}// 测试自定义实现性能std::clock_t custom_start = std::clock();for (int i = 0; i < TEST_ITERATIONS; i++) {aes128_cfb_encrypt(output_buffer.data(), input_buffer.data(), len, iv, round_key);}double custom_time = (std::clock() - custom_start) / (double)CLOCKS_PER_SEC;// 测试OpenSSL实现性能std::clock_t openssl_start = std::clock();for (int i = 0; i < TEST_ITERATIONS; i++) {openssl_aes128_cfb_encrypt(output_buffer.data(), input_buffer.data(), len, key, iv);}double openssl_time = (std::clock() - openssl_start) / (double)CLOCKS_PER_SEC;// 计算吞吐量 (MB/s)double total_bytes = len * TEST_ITERATIONS;double custom_throughput = (total_bytes / (1024.0 * 1024.0)) / custom_time;double openssl_throughput = (total_bytes / (1024.0 * 1024.0)) / openssl_time;// 输出性能报告std::cout << "\n=== 性能测试 (10万次加密) ===";std::cout << "\n数据长度: " << len << " 字节";std::cout << "\n总数据量: " << std::fixed << std::setprecision(2) << total_bytes / (1024.0 * 1024.0) << " MB\n";std::cout << "\n自定义实现:";std::cout << "\n  总时间: " << std::fixed << std::setprecision(5) << custom_time << " 秒";std::cout << "\n  平均时间: " << std::fixed << std::setprecision(5) << custom_time * 1000 / TEST_ITERATIONS << " 毫秒/次";std::cout << "\n  吞吐量: " << std::fixed << std::setprecision(2) << custom_throughput << " MB/s\n";std::cout << "\nOpenSSL 实现:";std::cout << "\n  总时间: " << std::fixed << std::setprecision(5) << openssl_time << " 秒";std::cout << "\n  平均时间: " << std::fixed << std::setprecision(5) << openssl_time * 1000 / TEST_ITERATIONS << " 毫秒/次";std::cout << "\n  吞吐量: " << std::fixed << std::setprecision(2) << openssl_throughput << " MB/s\n";// 性能比较std::cout << "\n性能比较:";if (custom_time < openssl_time) {double faster = (openssl_time - custom_time) / openssl_time * 100;std::cout << "\n  自定义实现比OpenSSL快 " << std::fixed << std::setprecision(2) << faster << "%";} else {double faster = (custom_time - openssl_time) / custom_time * 100;std::cout << "\n  OpenSSL比自定义实现快 " << std::fixed << std::setprecision(2) << faster << "%";}std::cout << "\n  吞吐量比率: " << std::fixed << std::setprecision(2) << custom_throughput / openssl_throughput << "x\n";
}int main() {std::cout << "=== AES-128-CFB 实现验证 ===\n";// 首先运行自测试(包含与OpenSSL的对比)if (!test_aes128_cfb()) {std::cerr << "\n实现验证失败,请检查代码!\n";return 1;}// 示例密钥(128位 = 16字节)uint8_t key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};// 示例IV(128位 = 16字节)uint8_t iv[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};// 测试数据const char* plaintext = "Hello, AES-128-CFB! This is a test message for encryption and decryption. ""This additional text is to make the test data longer for more meaningful performance testing. ""AES (Advanced Encryption Standard) is a specification for the encryption of electronic data ""established by the U.S. National Institute of Standards and Technology (NIST) in 2001.";size_t len = strlen(plaintext);// 扩展密钥存储 (11轮)__m128i round_key[11];aes128_key_expansion(key, round_key);// 运行性能测试performance_test(key, iv, (const uint8_t*)plaintext, len, round_key);return 0;
}

http://www.xdnf.cn/news/982423.html

相关文章:

  • c++ std::invoke
  • influxdb3常用查询命令
  • 小型综合实验拓扑图(eNSP)
  • [学习] Costas环详解:从原理到实战
  • MCGS和1200plc变量表格式编辑
  • [docker]--解析 Docker 镜像拉取日志:状态与分层拉取逻辑
  • Cohen–Grossberg神经网络
  • python 实现决策树规则
  • 变压吸附制氮设备的工艺特点
  • OAuth 2.0中/oauth/authorize接口的核心作用解析
  • 【数据分析】RNA-seq 数据分析:差异表达、火山图与功能富集分析
  • 「日立涡旋压缩机」携手企企通,打造AI数智供应链协同新范式
  • 嵌入式开发学习日志(数据库II 网页制作)Day38
  • 计算机网络 : 数据链路层
  • (十)量子注意力机制:深度学习与量子计算的交叉融合探索
  • Linux【7】------Linux系统编程(进程间通信IPC)
  • YOLOv1 技术详解:目标检测的实时革命
  • mac电脑.sh文件,用来清除git当前分支
  • 【深度学习:进阶篇】--2.4.BN与神经网络调优
  • 曼昆《经济学原理》第九版 第十六章垄断竞争
  • UE5创建3D 按钮
  • Mac安装docker desktop
  • 云原生核心技术 (12/12): 终章:使用 GitLab CI 将应用自动部署到 K8s (保姆级教程)
  • C++037(复制、比较、长度字符数组)
  • `document.domain` API 的废弃与现代 Web 开发的转型
  • 归并排序详解:优雅的分治艺术
  • 实现 Spring Boot 3的组合注解,java
  • S2B2B农产品供应链交易多平台开发有哪些发展前景?如何维护?
  • docker 安装postgre并使用php进行连接
  • Spring MVC完全指南 - 从入门到精通