我很好奇使用向量运算实现恒定时间比较是否有问题。天真的,似乎绝对没有泄漏任何可操作的信息,因为所有字节都是使用占用相同时间量的操作进行比较的,而与输入无关。但是,代码的矢量化部分和非矢量化部分之间肯定存在可测量的差异,因此有人想知道这是否可以以任何方式滥用...
/// <summary>
/// Compares the contents of two spans for equality in constant time.
/// </summary>
/// <param name="x">The first span that will be compared.</param>
/// <param name="y">The second span that will be compared.</param>
public static bool CompareInConstantTime(ReadOnlySpan<byte> x, ReadOnlySpan<byte> y) {
var min = ((x.Length > y.Length) ? y.Length : x.Length);
var max = ((x.Length < y.Length) ? y.Length : x.Length);
var offset = 0;
var result = 0;
var z = (Span<byte>)stackalloc byte[] { byte.MinValue, byte.MaxValue };
if (Vector.IsHardwareAccelerated) {
var vectorX = MemoryMarshal.Cast<byte, Vector<byte>>(x.Slice(0, min));
var vectorY = MemoryMarshal.Cast<byte, Vector<byte>>(y.Slice(0, min));
var vectorCount = vectorX.Length;
var vectorResult = Vector<byte>.Zero;
for (var i = offset; (i < vectorCount); i++) {
vectorResult |= (vectorX[i] ^ vectorY[i]);
}
offset = (Vector<byte>.Count * vectorCount);
result |= (Vector<byte>.Zero == vectorResult ? byte.MinValue : byte.MaxValue);
}
for (var i = offset; (i < min); i++) {
result |= (x[i] ^ y[i]);
}
for (var i = min; (i < max); i++) {
result |= (z[0] ^ z[1]);
}
return (0 == result);
}