ceesb/DifferentialPowerAttacks.jl

GitHub: ceesb/DifferentialPowerAttacks.jl

一个用于对密码学计算进行相关性/差分功耗分析侧信道攻击的 Julia 库,支持模块化的预测器与泄漏模型以及批量迹数据处理。

Stars: 0 | Forks: 0

[![](https://img.shields.io/badge/docs-green.svg)](https://ceesb.github.io/DifferentialPowerAttacks.jl/) # DifferentialPowerAttacks 一个用于相关性/差分功耗分析攻击的 Julia 库。 `DifferentialPowerAttacks` 将攻击拆分为预测器、泄漏模型、迹数据和 测量样本。它内部使用了 `BatchStats`,因此迹可以分批处理,并且独立 累积的攻击可以合并。 目前本库仅包含针对 AES 的攻击,但该库极易扩展到其他攻击,您无需将其嵌入到 `DifferentialPowerAttacks` 中即可实现这些攻击。 ## 示例 首先,是对一个密钥字节进行的简单第一轮 AES S-box 攻击。 ``` using DifferentialPowerAttacks import DifferentialPowerAttacks: leak, predict ntraces = 1000 nsamples = 40 data = rand(UInt8, 16, ntraces) samples = rand(UInt8, nsamples, ntraces) predictor = AesSbox{1}() leakagemodel = HammingWeightLM() secretkey = rand(UInt8) # 对于此示例,请在样本 19 处放置一个精确的模拟泄漏。 samples[19, :] = [ leak(leakagemodel, 1, predict(predictor, input, secretkey)) for input in eachcol(data) ] attack = run_attack(predictor, leakagemodel, data, samples) scores = getScores(attack) |> vec guess = UInt8(sortperm(scores, rev = true)[1] - 1) @show guess, secretkey ``` 迹数据按列排列: - `data` 是一个 `ndata x ntraces` 矩阵。每一列是 一条迹的公开输入。 - `samples` 是一个 `nsamples x ntraces` 矩阵。每一列是对应 `data` 列的测量功耗迹。 分数通过密钥候选值加一进行索引。对于一个 8 位密钥字节,候选值 `0x2a` 存储在 `scores[0x2a + 1]` 处。 ## 预测器 预测器将公开的迹输入和密钥候选值映射为一个中间值。 目前可用的 AES 预测器有: - `AesSbox{N}()` 预测输入字节 `N` 的第一轮 S-box 输出。 - `AesMcol{R,C}(T)` 预测行 `R`、列 `C` 的 32 位第一轮 MixColumns 贡献,其中 `T = makeT()` 来自 `AESInternals`。 - `AesSboxHD{R,C}()` 预测行 `R`、列 `C` 的第一轮和第二轮 S-box 输出之间的字节汉明距离 (Hamming distance)。 您可以同时攻击多个兼容的预测器: ``` predictors = (AesSbox{1}(), AesSbox{2}()) leakagemodels = (IdentityLM(), HammingWeightLM(), BitsLM()) attack = run_attack(predictors, leakagemodels, data, samples) scores = getScores(attack) ``` 一起使用的预测器必须具有相同数量的密钥候选值和 相同的预测值类型。 ## 泄漏模型 泄漏模型将预测值映射为假设的泄漏值。 内置的泄漏模型包括: - `IdentityLM()`:直接使用预测值。 - `HammingWeightLM()`:使用 `count_ones(prediction)`。 - `BitsLM()`:每个位输出一个值,对于 `UInt8` 预测输出 8 个结果,对于 `UInt32` 预测输出 32 个结果。 一起使用的泄漏模型必须为相同的预测值类型生成相同的 泄漏元素类型。 ## 批处理与聚合更新 您可以分块处理迹并合并累积的统计数据。 ``` import DifferentialPowerAttacks: CPAttack, add! attack1 = run_attack(predictor, leakagemodel, data[:, 1:500], samples[:, 1:500]) attack2 = run_attack(predictor, leakagemodel, data[:, 501:1000], samples[:, 501:1000]) add!(attack1, attack2) scores = getScores(attack1) ``` 您还可以创建一个攻击累加器,稍后再向其输入更多迹。 ``` attack = CPAttack(predictor, leakagemodel, nsamples) run_attack(attack, data[:, 1:500], samples[:, 1:500]) run_attack(attack, data[:, 501:1000], samples[:, 501:1000]) ``` ## 嵌入到其他代码中 如果您将此库嵌入到更大的捕获、解析或处理流水线中, 您可能不希望由 `run_attack(...)` 来接管完整的迹循环。该方法 是一个针对矩阵形式输入的便捷包装器。在应用代码中,通常 更简洁的做法是一次性创建 `CPAttack` 实例,并在有迹或迹批次可用时调用 `add`。 ``` using DifferentialPowerAttacks import DifferentialPowerAttacks: CPAttack, add! predictor = AesSbox{1}() leakagemodel = HammingWeightLM() nsamples = 40 attack = CPAttack(predictor, leakagemodel, nsamples) for _ in 1 : 1000 input = rand(UInt8, 16) trace = rand(UInt8, nsamples) add!(attack, trace, input) end scores = getScores(attack) |> vec ``` 为了获得更高的吞吐量,请使用矩阵而不是单个迹来调用 `add!`: ``` inputs = rand(UInt8, 16, 128) traces = rand(UInt8, nsamples, 128) add!(attack, traces, inputs) ``` ## 进度与序列化 有两个简单的日志记录器。 ``` logger = (ConsoleProgressLogger(10.0),) attack = run_attack(predictor, leakagemodel, data, samples; logger = logger) ``` `ConsoleProgressLogger` 会在攻击运行时打印排名靠前的密钥候选值。 `ScoresSerializer` 会定期序列化累积的 `CPAttack` 快照。 ``` logger = (ScoresSerializer("scores.bin", 10_000),) attack = run_attack(predictor, leakagemodel, data, samples; logger = logger) ``` ## 自定义预测器和泄漏模型 用户可以定义自己的预测器和泄漏模型。预测器应当 继承其预测值类型的 `Predictor{T}`,并实现 `predict` 和 `nkeys`。 ``` import DifferentialPowerAttacks: Predictor, predict, nkeys struct MyPredictor <: Predictor{UInt8} end predict(::MyPredictor, input, keycandidate) = input[1] ⊻ UInt8(keycandidate) nkeys(::MyPredictor) = 256 ``` 泄漏模型应当继承 `LeakageModel` 并实现 `leak`、`noutputs` 和 `leaktype`。 ``` import DifferentialPowerAttacks: LeakageModel, leak, noutputs, leaktype struct LowNibbleLM <: LeakageModel end noutputs(::LowNibbleLM, ::Type{UInt8}) = 1 leaktype(::LowNibbleLM, ::Type{UInt8}) = UInt8 leak(::LowNibbleLM, _, prediction) = prediction & 0x0f ```
标签:AES, Julia, 侧信道攻击, 密码学, 差分功耗分析, 手动系统调用