| ... | @@ -334,31 +334,6 @@ test "mem.secureZero" { | ... | @@ -334,31 +334,6 @@ test "mem.secureZero" { |
| 334 | testing.expectEqualSlices(u8, a[0..], b[0..]); | 334 | testing.expectEqualSlices(u8, a[0..], b[0..]); |
| 335 | } | 335 | } |
| 336 | | 336 | |
| 337 | /// Constant-time (for a given length) comparison. | | |
| 338 | pub fn timingSafeEqual(comptime T: type, a: []const T, b: []const T) bool { | | |
| 339 | const length = a.len; | | |
| 340 | if (length != b.len) { | | |
| 341 | return false; | | |
| 342 | } | | |
| 343 | const ap = @ptrCast([*]const volatile T, a.ptr); | | |
| 344 | const bp = @ptrCast([*]const volatile T, b.ptr); | | |
| 345 | var c: u8 = 0; | | |
| 346 | var i: usize = 0; | | |
| 347 | while (i < length) : (i += 1) { | | |
| 348 | c |= a[i] ^ b[i]; | | |
| 349 | } | | |
| 350 | return c == 0; | | |
| 351 | } | | |
| 352 | | | |
| 353 | test "mem.timingSafeEqual" { | | |
| 354 | var a = [_]u8{0xfe} ** 8; | | |
| 355 | var b = [_]u8{0xfe} ** 8; | | |
| 356 | | | |
| 357 | testing.expect(timingSafeEqual(u8, &a, &b)); | | |
| 358 | a[0] += 1; | | |
| 359 | testing.expect(!timingSafeEqual(u8, &a, &b)); | | |
| 360 | } | | |
| 361 | | | |
| 362 | /// Initializes all fields of the struct with their default value, or zero values if no default value is present. | 337 | /// Initializes all fields of the struct with their default value, or zero values if no default value is present. |
| 363 | /// If the field is present in the provided initial values, it will have that value instead. | 338 | /// If the field is present in the provided initial values, it will have that value instead. |
| 364 | /// Structs are initialized recursively. | 339 | /// Structs are initialized recursively. |