DoxigAlpha

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");
        },
    }
}