当前位置:首页 > OpenCL&HLS > 正文内容

使用Vitis HLS实现和优化SPECK加解密函数

chanra1n2个月前 (05-31)OpenCL&HLS398

设计代码如下:

// speck_hls.cpp
#include "ap_int.h"

// 定义密钥和回合数
#define WORD_SIZE 16
#define KEY_SIZE 4
#define NUM_ROUNDS 22

typedef ap_uint<WORD_SIZE> half_word;
typedef ap_uint<WORD_SIZE*2> word;
typedef ap_uint<WORD_SIZE*4> key_type;

// 定义流水线节拍
#define PIPELINE_II 1

// SPECK加密算法
void speck_encrypt(word plaintext, word* ciphertext, const half_word key_schedule[NUM_ROUNDS]) {
    half_word left = plaintext(WORD_SIZE*2-1, WORD_SIZE);
    half_word right = plaintext(WORD_SIZE-1, 0);

SPECK_ENCRYPT_LOOP:
    for (int i = 0; i < NUM_ROUNDS; i++) {
#pragma HLS PIPELINE II=PIPELINE_II
        left = (right + left) % (1 << WORD_SIZE);
        left ^= key_schedule[i];
        right = (right >> 7) | (right << (WORD_SIZE - 7));
        right ^= left;
    }

    *ciphertext = (left, right);
}

// SPECK解密算法
void speck_decrypt(word ciphertext, word* plaintext, const half_word key_schedule[NUM_ROUNDS]) {
    half_word left = ciphertext(WORD_SIZE*2-1, WORD_SIZE);
    half_word right = ciphertext(WORD_SIZE-1, 0);

SPECK_DECRYPT_LOOP:
    for (int i = NUM_ROUNDS-1; i >= 0; i--) {
#pragma HLS PIPELINE II=PIPELINE_II
        right ^= left;
        right = (right << 7) | (right >> (WORD_SIZE - 7));
        left ^= key_schedule[i];
        left = (left - right) % (1 << WORD_SIZE);
    }

    *plaintext = (left, right);
}

// 密钥扩展
void key_expansion(const key_type key, half_word key_schedule[NUM_ROUNDS]) {
    half_word l[NUM_ROUNDS];
    half_word k = key(KEY_SIZE*WORD_SIZE-1, (KEY_SIZE-1)*WORD_SIZE);

    l[0] = key((KEY_SIZE-2)*WORD_SIZE-1, (KEY_SIZE-3)*WORD_SIZE);
    key_schedule[0] = k;

KEY_EXPANSION_LOOP:
    for (int i = 0; i < NUM_ROUNDS-1; i++) {
#pragma HLS PIPELINE II=PIPELINE_II
        l[i+1] = (k + l[i]) % (1 << WORD_SIZE);
        l[i+1] ^= i;
        k = (k >> 7) | (k << (WORD_SIZE - 7));
        k ^= l[i+1];
        key_schedule[i+1] = k;
    }
}

// 重构的顶层函数
void speck(word plaintext, word* ciphertext, word* decrypted_text, const key_type key) {
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE s_axilite port=plaintext
#pragma HLS INTERFACE s_axilite port=ciphertext
#pragma HLS INTERFACE s_axilite port=decrypted_text
#pragma HLS INTERFACE s_axilite port=key

    half_word key_schedule[NUM_ROUNDS];

    // Key schedule calculation
    key_expansion(key, key_schedule);

    // 加密和解密操作
    word ciphertext_internal;
    word decrypted_text_internal;

    speck_encrypt(plaintext, &ciphertext_internal, key_schedule);
    speck_decrypt(ciphertext_internal, &decrypted_text_internal, key_schedule);

    // 将结果写入输出
    *ciphertext = ciphertext_internal;
    *decrypted_text = decrypted_text_internal;
}

测试代码如下:

// test_speck_hls.cpp
#include <iostream>
#include <stdio.h>
#include "ap_int.h"

#define WORD_SIZE 16
#define KEY_SIZE 4
#define NUM_ROUNDS 22

typedef ap_uint<WORD_SIZE> half_word;
typedef ap_uint<WORD_SIZE*2> word;
typedef ap_uint<WORD_SIZE*4> key_type;

void speck(word plaintext, word* ciphertext, word* decrypted_text, const key_type key);

// 自动化测试函数
bool run_test(word plaintext, const key_type key) {
    word ciphertext;
    word decrypted_text;

    // 调用SPECK函数进行加密和解密
    speck(plaintext, &ciphertext, &decrypted_text, key);

    // 检查解密结果是否与原始明文匹配
    return (plaintext == decrypted_text);
}

int main() {
    // 测试数据
    word plaintexts[] = {0x6574694c, 0x12345678, 0xABCDEF01, 0x0FEDCBA9};
    key_type keys[] = {0x1918111009080100, 0x1A1B1C1D0E0F1011, 0x2021222324252627, 0x1314151607181920};
    int num_tests = sizeof(plaintexts) / sizeof(plaintexts[0]);

    // 记录通过和失败的测试数量
    int passed_tests = 0;
    int failed_tests = 0;

    // 测试每组明文和密钥
    for (int i = 0; i < num_tests; i++) {
        bool result = run_test(plaintexts[i], keys[i]);
        if (result) {
            passed_tests++;
            printf("Test %d passed\n", i+1);
        } else {
            failed_tests++;
            printf("Test %d failed\n", i+1);
        }
    }

    printf("Total tests passed: %d\n", passed_tests);
    printf("Total tests failed: %d\n", failed_tests);

    return 0;
}

编译结果:

image.png

扫描二维码推送至手机访问。

版权声明:本文由我的FPGA发布,如需转载请注明出处。

本文链接:http://myfpga.cn/index.php/post/426.html

分享给朋友:

“使用Vitis HLS实现和优化SPECK加解密函数” 的相关文章

Ubuntu下Quartus OpenCL实现手写数字识别 QuartusPro 18.1 Update2 Arria10

Ubuntu下Quartus OpenCL实现手写数字识别 QuartusPro 18.1 Update2 Arria10

环境:Arria10 FPGA 10AXF40GAE 10AXF40GAAAMD Ryzen™ 7 7735HS 8核16线程(实测编译速度与主频和核心数有关,可以上X99的双路服务器)英睿达DDR5 4800Mhz 32G*2(注意,内存应大于8G,并且越大越好,否则...

OpenCL运行报错分析与解决MMD INFO : [board0] PCIe-to-fabric read test failed, read 0xffffffff after  1 attempt

OpenCL运行报错分析与解决MMD INFO : [board0] PCIe-to-fabric read test failed, read 0xffffffff after 1 attempt

在运行opencl程序或者aocl program时,发生报错:MMD INFO : [board0] PCIe-to-fabric read test failed, read 0xffffffff ...

Intel N3000 PAC开发板 Arria10FPGA 100G智能网卡 支持PCIE程序上传/调试 OpenCL OPAE

Intel N3000 PAC开发板 Arria10FPGA 100G智能网卡 支持PCIE程序上传/调试 OpenCL OPAE

近期,从小黄鱼上收了两块N3000的Intel PAC板子,FPGA型号和Microsoft 1768那个差不多,区别是这个支持100G网口,但是DDR4只有9G(组合后为9G)。型号是10AT115S1F45E1SG先把坑说前面,解决了能减少很多麻烦:To compile an AFU using...

使用Vitis HLS实现和优化Conv2D函数

使用Vitis HLS实现和优化Conv2D函数

现代卷积神经网络(CNNs)中,卷积操作(Conv2D)是最基本且计算量集中的部分。为了在嵌入式系统和FPGA平台上加速这一计算,我们可以利用Xilinx的Vitis高层次综合(HLS)工具。本文将介绍如何使用Vitis HLS实现一个基础的卷积操作,随后进行各种优化以提高其性能。一、基础实现我们首...

 使用Vitis HLS实现和优化DethSepConv函数

使用Vitis HLS实现和优化DethSepConv函数

1初版功能验证1.0设计框图+-----------------------------------+ |            Input Data &nb...

通俗易懂的Quartus HLS vs Vitis HLS 优化技巧及对比

通俗易懂的Quartus HLS vs Vitis HLS 优化技巧及对比

随着深度学习应用的普及,FPGA作为强大且高效的硬件加速器,其高性能和低延迟特性备受关注。为了简化FPGA开发流程,高级综合工具(HLS)如Intel的Quartus HLS和Xilinx的Vitis HLS相继推出,为用户提供了基于C/C++的编程方式,从而降低了开发门槛。然而,如何使用这些工具进...