【问题标题】:How to implement input independent logical shift in software?如何在软件中实现输入无关的逻辑移位?
【发布时间】:2022-11-15 19:39:33
【问题描述】:
我正在尝试在软件中实现 AES/DES/.. 加密/解密,而不使用任何输入相关操作(特别是仅使用恒定时间,而不是和,或,异或操作和输入独立数组索引/循环)。
有没有办法实现输入独立的逻辑移位(someconst << key[3] & 5 等)?
具有输入因变量的数组索引,使用与输入相关的 n 的硬件移位,必须避免与输入相关的条件跳转,我不关心代码大小/速度。
【问题讨论】:
标签:
cryptography
language-agnostic
bit-shift
side-channel-attacks
【解决方案1】:
根据您的要求以及您可以假设哪些操作是常数时间,此代码需要一些额外的修改。
但是,它可能会为您指明正确的方向(因为 SELECT 原语对于边信道免费代码非常强大):
#define MAX_SHIFT 32 // maximum amount to be shifted
// this may not be constant time.
// However, you can find different (more ugly) ways to achieve the same thing.
// 1 -> 0
// 0 -> 0xff...
#define MASK(cond) (cond - 1)
// again, make sure everything here is constant time according to your threat model
// (0, x, y) -> y
// (i, x, y) -> x (i != 0)
#define SELECT(cond, A, B) ((MASK(!(cond)) & A) | (MASK(!!(cond)) & B))
int shift(int value, int shift){
int result = value;
for(int i = 0; i <= MAX_SHIFT; i++){
result = SELECT(i ^ shift, result, value);
// this may not be constant time. If it is not, implement it yourself ;)
value <<= 1;
}
return result;
}
但是请注意,您必须确保编译器不会对此进行优化。
此外,CPU 还可能采用与操作数相关的性能优化,这可能会导致时序差异。
除此之外,像 Spectre 这样的瞬时执行攻击也可能是一种威胁。
结论:几乎不可能编写无边信道代码。