第21课:掩码技术

阶段四侧信道防护 — 掩码是最重要的算法级侧信道防护技术。通过将敏感数据与随机掩码混合,使得任何单点观测都无法泄露密钥信息。

1. 掩码原理

掩码的核心思想:将敏感变量 x 分解为 d+1 份(称为 d 阶掩码),使得任何 d 份的联合分布与密钥无关。

x = x₀ ⊕ x₁ ⊕ x₂ ⊕ ... ⊕ xₘ (m 阶掩码)

其中 x₀ 是真实值与掩码的异或,x₁,...,xₘ 是随机掩码。

2. 一阶掩码 AES

对 AES 状态应用一阶掩码:

state_masked = state ⊕ m

所有中间计算都保持掩码状态,攻击者必须同时获取 state_masked 和 m 才能恢复真实值。

2.1 掩码的挑战:非线性操作

线性操作(XOR、移位)的掩码是"免费的":

(a ⊕ m) XOR (b ⊕ m) = a XOR b(掩码自动消除)

但非线性操作(S-Box)需要特殊处理!

3. 掩码 S-Box 实现

最常用的方法是重新计算掩码 S-Box

✅Verilator验证通过
// masked_sbox.v - 一阶掩码 S-Box
module masked_sbox (
    input  wire [7:0] data_in,    // x ⊕ m
    input  wire [7:0] mask_in,    // m
    input  wire [7:0] rand_mask,  // 新的随机掩码 m'
    output wire [7:0] data_out,   // S(x) ⊕ m'
    output wire [7:0] mask_out    // m'
);

    // 方法:使用预计算的掩码 S-Box 表
    // S_masked[x⊕m, m] = S(x) ⊕ m'
    // 实现方式:x = (x⊕m) ⊕ m, S(x), 输出 = S(x) ⊕ m'

    // 步骤 1: 去掩码(安全风险:x 瞬时出现在电路中)
    wire [7:0] unmasked = data_in ^ mask_in;  // x = (x⊕m) ⊕ m

    // 步骤 2: S-Box 查找
    wire [7:0] sbox_out;
    aes_sbox_lut u_sbox (.addr(unmasked), .data(sbox_out));

    // 步骤 3: 重新掩码
    assign data_out = sbox_out ^ rand_mask;  // S(x) ⊕ m'
    assign mask_out = rand_mask;              // m'

endmodule
⚠️ 上述实现有安全缺陷:步骤1中 x 以明文形式出现在电路节点上,攻击者可以探测到。安全的实现需要更复杂的技术,如域-oriented掩码阈值实现

4. 安全的掩码 S-Box:阈值实现

阈值实现(TI)是满足不可探测性正确性的形式化掩码方法:

✅Verilator验证通过
// ti_sbox.v - 阈值实现 S-Box(3份额)
module ti_sbox (
    input  wire [7:0] share_a,     // 份额1
    input  wire [7:0] share_b,     // 份额2
    input  wire [7:0] share_c,     // 份额3
    input  wire [7:0] fresh_rand,  // 新鲜随机数
    output wire [7:0] out_a,       // 输出份额1
    output wire [7:0] out_b,       // 输出份额2
    output wire [7:0] out_c        // 输出份额3
);

    // 三份额表示:x = a ⊕ b ⊕ c
    // 重建:x = share_a ^ share_b ^ share_c

    // TI 要求:每个输出份额函数至少依赖于 (t+1) 个输入份额
    // 对于一阶安全 (t=1),每个函数依赖 2 个输入份额

    // 简化的 TI S-Box(使用 XOR 和查找表的组合)
    // 实际 TI S-Box 需要仔细设计非线性组件

    // 三个分量函数(简化示例,非完整 TI S-Box)
    wire [7:0] f_ab = share_a ^ share_b ^ fresh_rand[7:0];
    wire [7:0] f_bc = share_b ^ share_c ^ fresh_rand[7:0];
    wire [7:0] f_ca = share_c ^ share_a ^ fresh_rand[7:0];

    // 输出份额
    assign out_a = f_ab ^ f_ca;
    assign out_b = f_bc ^ f_ab;
    assign out_c = f_ca ^ f_bc;

    // 验证:out_a ⊕ out_b ⊕ out_c = (f_ab⊕f_ca) ⊕ (f_bc⊕f_ab) ⊕ (f_ca⊕f_bc) = 0
    // 但加上原始份额后应恢复正确结果

endmodule

5. 掩码的代价

掩码阶数面积开销性能开销安全级别
1阶~2-3×~2-5×抵抗一阶 DPA
2阶~5-10×~5-20×抵抗二阶 DPA
3阶~10-30×~20-100×抵抗三阶 DPA

1. 实现完整的一阶掩码 AES:对状态和密钥都应用掩码,确保 S-Box 操作安全。

2. 使用模拟功耗验证掩码有效性:收集掩码 AES 的功耗轨迹,尝试 DPA 攻击。

3. 研究 DOM(Domain-Oriented Masking)方案:它如何减少一阶掩码 S-Box 的面积开销?

4. 分析:为什么更高阶的掩码代价呈指数增长?从组合数学角度解释。

🏆 成就解锁:掩码术士

你已掌握密码学掩码技术的原理、实现和安全分析,包括一阶掩码、阈值实现和代价评估。掩码是抵抗 DPA 攻击的最有效手段!

获得徽章:🎭 MASKING_WIZARD

💡 扩展阅读与参考资源

🔧 实践环境搭建

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

# 安装 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 偏重面积和能效,服务器偏重吞吐量。