ConstantTimeByteEq如何工作?

时间:2013-07-11 21:04:09

标签: go bit-manipulation

在Go的加密库中,我发现了这个函数ConstantTimeByteEq。它做了什么,它是如何工作的?

// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
func ConstantTimeByteEq(x, y uint8) int {
    z := ^(x ^ y)
    z &= z >> 4
    z &= z >> 2
    z &= z >> 1

    return int(z)
}

2 个答案:

答案 0 :(得分:7)

x ^ yx XOR y,x和y的结果为1,y为不同,0为相同的位:

x            = 01010011
y            = 00010011
x ^ y        = 01000000

^(x ^ y)否定了这一点,即你得到的是不同的比特为0,否则为1:

^(x ^ y)     = 10111111 => z

然后我们开始将z向右移动以单独屏蔽其位。换档用零位填充数字的左侧:

z >> 4       = 00001011

目标是将z中的任意零传播到结果中,启动ANDing:

z            = 10111111
z >> 4       = 00001011
z & (z >> 4) = 00001011

也折叠新值以向右移动任何零:

z            = 00001011
z >> 2       = 00000010
z & (z >> 2) = 00000010

进一步折叠到最后一位:

z            = 00001010
z >> 1       = 00000001
z & (z >> 1) = 00000000

另一方面,如果你最初有x == y,那就是这样:

z            = 11111111
z (& z >> 4) = 00001111
z (& z >> 2) = 00000011
z (& z >> 1) = 00000001

所以它在x == y时真的返回1,否则为0。

通常,如果x和y都为零,则比较可以比其他情况花费更少的时间。此函数尝试使其无论输入的值如何,所有调用都会占用相同的时间。这样,攻击者就无法使用基于时间的攻击。

答案 1 :(得分:6)

它完全符合文档所说的内容:它检查x和y是否相等。从功能上看它只是x == y,简单易懂。

以这种神秘的bit-fiddling方式执行x == y可防止对算法的定时端攻击:如果x = y,则x == y可编译为执行速度更快的代码,如果x!= y则执行速度更慢(或者相反)由于CPU中的分支预测。攻击者可以使用它来了解加密例程处理的数据,从而危及安全性。