| ... | ... | @@ -334,31 +334,6 @@ test "mem.secureZero" { |
| 334 | 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 | 337 | /// Initializes all fields of the struct with their default value, or zero values if no default value is present. |
| 363 | 338 | /// If the field is present in the provided initial values, it will have that value instead. |
| 364 | 339 | /// Structs are initialized recursively. |