Function timingSafeCompare [src]

Alias for std.crypto.timing_safe.compare

Compare two integers serialized as arrays of the same size, in constant time. Returns .lt if ab and .eq if a=b

Prototype

pub fn compare(comptime T: type, a: []const T, b: []const T, endian: Endian) Order

Parameters

T: typea: []const Tb: []const Tendian: Endian

Example

test compare { const expectEqual = std.testing.expectEqual; var a = [_]u8{10} ** 32; var b = [_]u8{10} ** 32; try expectEqual(compare(u8, &a, &b, .big), .eq); try expectEqual(compare(u8, &a, &b, .little), .eq); a[31] = 1; try expectEqual(compare(u8, &a, &b, .big), .lt); try expectEqual(compare(u8, &a, &b, .little), .lt); a[0] = 20; try expectEqual(compare(u8, &a, &b, .big), .gt); try expectEqual(compare(u8, &a, &b, .little), .lt); }

Source

pub fn compare(comptime T: type, a: []const T, b: []const T, endian: Endian) Order { assert(a.len == b.len); const bits = switch (@typeInfo(T)) { .int => |cinfo| if (cinfo.signedness != .unsigned) @compileError("Elements to be compared must be unsigned") else cinfo.bits, else => @compileError("Elements to be compared must be integers"), }; const Cext = std.meta.Int(.unsigned, bits + 1); var gt: T = 0; var eq: T = 1; if (endian == .little) { var i = a.len; while (i != 0) { i -= 1; const x1 = a[i]; const x2 = b[i]; gt |= @as(T, @truncate((@as(Cext, x2) -% @as(Cext, x1)) >> bits)) & eq; eq &= @as(T, @truncate((@as(Cext, (x2 ^ x1)) -% 1) >> bits)); } } else { for (a, 0..) |x1, i| { const x2 = b[i]; gt |= @as(T, @truncate((@as(Cext, x2) -% @as(Cext, x1)) >> bits)) & eq; eq &= @as(T, @truncate((@as(Cext, (x2 ^ x1)) -% 1) >> bits)); } } if (gt != 0) { return Order.gt; } else if (eq != 0) { return Order.eq; } return Order.lt; }