eql
Compares two arrays in constant time (for a given length) and returns whether they are equal. This function was designed to compare short cryptographic secrets (MACs, signatures). For all other applications, use mem.eql() instead.
Function parameters
Parameters
- T:type
- a:T
- b:T
Compares two arrays in constant time (for a given length) and returns whether they are equal.
Functions
- eql
- Compares two arrays in constant time (for a given length) and returns whether they are equal.
- compare
- Compare two integers serialized as arrays of the same size, in constant time.
- add
- Add two integers serialized as arrays of the same size, in constant time.
- sub
- Subtract two integers serialized as arrays of the same size, in constant time.
- classify
- Mark a value as sensitive or secret, helping to detect potential side-channel vulnerabilities.
- declassify
- Mark a value as non-sensitive or public, indicating it's safe from side-channel attacks.
Source
Implementation
pub fn eql(comptime T: type, a: T, b: T) bool {
switch (@typeInfo(T)) {
.array => |info| {
const C = info.child;
if (@typeInfo(C) != .int) {
@compileError("Elements to be compared must be integers");
}
var acc = @as(C, 0);
for (a, 0..) |x, i| {
acc |= x ^ b[i];
}
const s = @typeInfo(C).int.bits;
const Cu = std.meta.Int(.unsigned, s);
const Cext = std.meta.Int(.unsigned, s + 1);
return @as(bool, @bitCast(@as(u1, @truncate((@as(Cext, @as(Cu, @bitCast(acc))) -% 1) >> s))));
},
.vector => |info| {
const C = info.child;
if (@typeInfo(C) != .int) {
@compileError("Elements to be compared must be integers");
}
const acc = @reduce(.Or, a ^ b);
const s = @typeInfo(C).int.bits;
const Cu = std.meta.Int(.unsigned, s);
const Cext = std.meta.Int(.unsigned, s + 1);
return @as(bool, @bitCast(@as(u1, @truncate((@as(Cext, @as(Cu, @bitCast(acc))) -% 1) >> s))));
},
else => {
@compileError("Only arrays and vectors can be compared");
},
}
}