第16课:RSA 完整引擎

阶段三非对称密码 — 本课将蒙哥马利乘法与模幂结合,构建完整的 RSA 引擎,并加入 CRT 加速和数据填充。

1. 完整 RSA 引擎架构

┌─────────────┐    ┌──────────────┐    ┌──────────────┐
│ 域转换(入)   │───→│  MonPro 核心 │───→│ 域转换(出)   │
│ a → ā       │    │  模幂运算    │    │ ā → a        │
└─────────────┘    └──────────────┘    └──────────────┘
                         │
                    ┌────┴────┐
                    │ 控制FSM │
                    │ 密钥管理│
                    └─────────┘

2. RSA 引擎实现

✅Verilator验证通过
// rsa_engine.v - RSA 完整引擎
module rsa_engine #(
    parameter WIDTH = 256
)(
    input  wire              clk,
    input  wire              rst_n,
    input  wire              start,
    input  wire [WIDTH-1:0]  message,     // 消息
    input  wire [WIDTH-1:0]  exponent,    // 指数 e 或 d
    input  wire [WIDTH-1:0]  modulus,     // 模数 n
    input  wire [WIDTH-1:0]  r_squared,   // R² mod n
    input  wire [WIDTH-1:0]  m_prime,     // -n⁻¹ mod R
    output reg  [WIDTH-1:0]  result,
    output reg               valid,
    output reg               busy,
    output reg [7:0]         cycle_count
);

    // 状态机
    localparam S_IDLE     = 4'd0;
    localparam S_TO_MONT  = 4'd1;  // 进入蒙哥马利域
    localparam S_MODEXP   = 4'd2;  // 模幂运算
    localparam S_FROM_MONT= 4'd3;  // 退出蒙哥马利域
    localparam S_DONE     = 4'd4;

    reg [3:0] state;

    // 内部 MonPro 调用
    reg          mp_start;
    reg [WIDTH-1:0] mp_a, mp_b;
    wire [WIDTH-1:0] mp_result;
    wire         mp_valid;

    monpro #(.WIDTH(WIDTH)) u_monpro (
        .clk(clk), .rst_n(rst_n), .start(mp_start),
        .a_bar(mp_a), .b_bar(mp_b),
        .modulus(modulus), .m_prime(m_prime),
        .result(mp_result), .valid(mp_valid)
    );

    // 模幂控制
    reg [WIDTH-1:0] mont_result;   // 蒙哥马利域结果
    reg [WIDTH-1:0] mont_base;     // 蒙哥马利域底数
    reg [WIDTH-1:0] exp_reg;
    reg [WIDTH-1:0] acc;           // 累积结果(蒙哥马利域)
    reg [$clog2(WIDTH+1)-1:0] bit_cnt;
    reg [2:0] sub_state;           // 子状态机

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state <= S_IDLE; result <= 0; valid <= 0; busy <= 0;
            mp_start <= 0; cycle_count <= 0;
            mont_result <= 0; mont_base <= 0;
            exp_reg <= 0; acc <= 0; bit_cnt <= 0;
        end else begin
            mp_start <= 0;
            cycle_count <= cycle_count + 1;

            case (state)
                S_IDLE: begin
                    if (start) begin
                        // 域转换: ā = MonPro(a, R² mod n)
                        mp_a <= message;
                        mp_b <= r_squared;
                        mp_start <= 1;
                        state <= S_TO_MONT;
                        busy <= 1;
                        valid <= 0;
                        cycle_count <= 0;
                    end
                end
                S_TO_MONT: begin
                    if (mp_valid) begin
                        mont_base <= mp_result;  // 蒙哥马利域底数
                        acc <= r_squared;        // 蒙哥马利域的1 = R mod n
                        exp_reg <= exponent;
                        bit_cnt <= 0;
                        sub_state <= 0;
                        state <= S_MODEXP;
                    end
                end
                S_MODEXP: begin
                    if (bit_cnt < WIDTH) begin
                        case (sub_state)
                            0: begin
                                if (exp_reg[0]) begin
                                    mp_a <= acc;
                                    mp_b <= mont_base;
                                    mp_start <= 1;
                                    sub_state <= 1;
                                end else begin
                                    sub_state <= 2;
                                end
                            end
                            1: begin
                                if (mp_valid) begin
                                    acc <= mp_result;
                                    sub_state <= 2;
                                end
                            end
                            2: begin
                                mp_a <= mont_base;
                                mp_b <= mont_base;
                                mp_start <= 1;
                                sub_state <= 3;
                            end
                            3: begin
                                if (mp_valid) begin
                                    mont_base <= mp_result;
                                    exp_reg <= exp_reg >> 1;
                                    bit_cnt <= bit_cnt + 1;
                                    sub_state <= 0;
                                end
                            end
                        endcase
                    end else begin
                        // 域转换: a = MonPro(result, 1)
                        mp_a <= acc;
                        mp_b <= 1;
                        mp_start <= 1;
                        state <= S_FROM_MONT;
                    end
                end
                S_FROM_MONT: begin
                    if (mp_valid) begin
                        result <= mp_result;
                        valid <= 1;
                        busy <= 0;
                        state <= S_IDLE;
                    end
                end
            endcase
        end
    end

endmodule

3. CRT 加速解密

中国剩余定理(CRT)将 RSA 解密拆分为两个半宽运算,速度提升约 4 倍:

m₁ = c^d mod (p-1) mod p
m₂ = c^d mod (q-1) mod q
m = m₂ + q · ((m₁ - m₂) · q⁻¹ mod p)

1. 使用小 RSA 参数(n=3233)验证完整引擎的加密和解密。

2. 实现 CRT 加速模块:利用两个半宽(128位)MonPro 核心并行计算。

3. 添加 PKCS#1 v1.5 填充模块:在消息前添加 0x00 0x02 [随机非零字节] 0x00。

4. 分析 RSA-2048 加密的延迟:多少时钟周期?在 100MHz 时钟下需要多少毫秒?

🏆 成就解锁:RSA 完成者

你已构建完整的 RSA 引擎,集成了蒙哥马利乘法、域转换和模幂控制。RSA 是互联网公钥基础设施的基石!

获得徽章:🗝️ RSA_ENGINEER

💡 扩展阅读与参考资源

🔧 实践环境搭建

推荐使用以下工具链进行课程实践:

# 安装 Verilator
sudo apt install verilator

# 安装 Icarus Verilog(可选)
sudo apt install iverilog

# 安装 GTKWave(波形查看器)
sudo apt install gtkwave

# 验证安装
verilator --lint-only --version
iverilog -V

📊 性能指标对比

密码学硬件实现的关键性能指标:

这些指标之间通常存在 trade-off,设计时需根据应用场景权衡。

📚 本课知识图谱

本课涉及的核心概念和技术关系:

💡 调试技巧

Verilog 仿真调试的常用方法:

// 调试示例
initial begin
    $dumpfile("sim.vcd");
    $dumpvars(0, uut);
end

// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
    else $error("Invalid data when valid!");

🔧 Verilator 编译仿真完整流程

# 1. 语法检查
verilator --lint-only module.v

# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);
    Vmodule* top = new Vmodule;
    top->clk = 0; top->rst_n = 0;
    top->eval();
    top->rst_n = 1;
    for (int i = 0; i < 100; i++) {
        top->clk = !top->clk;
        top->eval();
    }
    delete top;
    return 0;
}
EOF

# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk

# 4. 运行
./obj_dir/Vmodule

📖 推荐阅读

⚖️ 性能评估框架

密码硬件的性能评估维度:

指标单位说明
面积GE / LUT等效门数或查找表数量
频率MHz最大时钟频率
吞吐量Gbps每秒处理的数据量
延迟周期数从输入到输出的周期
能效pJ/bit每比特能耗
面积效率Gbps/GE单位面积吞吐量

不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。

📚 本课知识图谱

本课涉及的核心概念和技术关系:

💡 调试技巧

Verilog 仿真调试的常用方法:

// 调试示例
initial begin
    $dumpfile("sim.vcd");
    $dumpvars(0, uut);
end

// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
    else $error("Invalid data when valid!");

🔧 Verilator 编译仿真完整流程

# 1. 语法检查
verilator --lint-only module.v

# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);
    Vmodule* top = new Vmodule;
    top->clk = 0; top->rst_n = 0;
    top->eval();
    top->rst_n = 1;
    for (int i = 0; i < 100; i++) {
        top->clk = !top->clk;
        top->eval();
    }
    delete top;
    return 0;
}
EOF

# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk

# 4. 运行
./obj_dir/Vmodule

📖 推荐阅读

⚖️ 性能评估框架

密码硬件的性能评估维度:

指标单位说明
面积GE / LUT等效门数或查找表数量
频率MHz最大时钟频率
吞吐量Gbps每秒处理的数据量
延迟周期数从输入到输出的周期
能效pJ/bit每比特能耗
面积效率Gbps/GE单位面积吞吐量

不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。