aboutsummaryrefslogtreecommitdiff
path: root/lib/std/mem.zig
diff options
context:
space:
mode:
authorFrank Denis <github@pureftpd.org>2020-08-14 14:06:18 +0200
committerAndrew Kelley <andrew@ziglang.org>2020-08-16 22:35:27 -0700
commit3f0d80f25eccd12759bad21fb8429e646eff070b (patch)
treecbb337e93ba6cb04c7ee26008a99f3c0b502e9e7 /lib/std/mem.zig
parentf46e375bbe0ac0893717bd477eab78f51863e277 (diff)
downloadzig-3f0d80f25eccd12759bad21fb8429e646eff070b.tar.gz
zig-3f0d80f25eccd12759bad21fb8429e646eff070b.zip
Improve curve25519-based crypto
This is a rewrite of the x25519 code, that generalizes support for common primitives based on the same finite field. - Low-level operations can now be performed over the curve25519 and edwards25519 curves, as well as the ristretto255 group. - Ed25519 signatures have been implemented. - X25519 is now about twice as fast. - mem.timingSafeEqual() has been added for constant-time comparison. Domains have been clearly separated, making it easier to later add platform-specific implementations.
Diffstat (limited to 'lib/std/mem.zig')
-rw-r--r--lib/std/mem.zig25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index 1ba64f47fa..dc26ed3d33 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -334,6 +334,31 @@ test "mem.secureZero" {
testing.expectEqualSlices(u8, a[0..], b[0..]);
}
+/// Constant-time (for a given length) comparison.
+pub fn timingSafeEqual(comptime T: type, a: []const T, b: []const T) bool {
+ const length = a.len;
+ if (length != b.len) {
+ return false;
+ }
+ const ap = @ptrCast([*]const volatile T, a.ptr);
+ const bp = @ptrCast([*]const volatile T, b.ptr);
+ var c: u8 = 0;
+ var i: usize = 0;
+ while (i < length) : (i += 1) {
+ c |= a[i] ^ b[i];
+ }
+ return c == 0;
+}
+
+test "mem.timingSafeEqual" {
+ var a = [_]u8{0xfe} ** 8;
+ var b = [_]u8{0xfe} ** 8;
+
+ testing.expect(timingSafeEqual(u8, &a, &b));
+ a[0] += 1;
+ testing.expect(!timingSafeEqual(u8, &a, &b));
+}
+
/// Initializes all fields of the struct with their default value, or zero values if no default value is present.
/// If the field is present in the provided initial values, it will have that value instead.
/// Structs are initialized recursively.