From a6795c6b60209f3c7516b67c6d76db7d59bbc012 Mon Sep 17 00:00:00 2001 From: Alexander van Ratingen <470642+alvra@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:43:53 +0200 Subject: [PATCH 1/3] Implement comparing strings. --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 795eade..8a10551 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -341,6 +341,13 @@ impl ConstantTimeEq for [T] { } } +impl ConstantTimeEq for str { + #[inline] + fn ct_eq(&self, rhs: &Self) -> Choice { + self.as_bytes().ct_eq(rhs.as_bytes()) + } +} + impl ConstantTimeEq for Choice { #[inline] fn ct_eq(&self, rhs: &Choice) -> Choice { From 6a202d5575ee25f291de7533d766f06161a189d3 Mon Sep 17 00:00:00 2001 From: Alexander van Ratingen <470642+alvra@users.noreply.github.com> Date: Tue, 13 Feb 2024 11:18:37 +0100 Subject: [PATCH 2/3] Document that string comparisons short-circuit if the lengths differ. --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 8a10551..da5cd85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -342,6 +342,13 @@ impl ConstantTimeEq for [T] { } impl ConstantTimeEq for str { + /// Check whether two strings are equal. + /// + /// # Note + /// + /// This function short-circuits if the lengths of the input strings + /// are different. Otherwise, it should execute in time independent + /// of the values. #[inline] fn ct_eq(&self, rhs: &Self) -> Choice { self.as_bytes().ct_eq(rhs.as_bytes()) From 52c3354b5bea4884ea20e8ad1dd11f93d0ba2196 Mon Sep 17 00:00:00 2001 From: Alexander van Ratingen <470642+alvra@users.noreply.github.com> Date: Sun, 18 Feb 2024 20:02:44 +0100 Subject: [PATCH 3/3] Add test for string comparisons. --- tests/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/mod.rs b/tests/mod.rs index f6b3982..90b7cb1 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -31,6 +31,13 @@ fn slices_equal() { assert_eq!(a_eq_c.unwrap_u8(), 0); } +#[test] +fn str_equal() { + assert_eq!("".ct_eq("").unwrap_u8(), 1); + assert_eq!("xxx".ct_eq("xxxx").unwrap_u8(), 0); + assert_eq!("abcd".ct_eq("abcd").unwrap_u8(), 1); +} + #[test] fn conditional_assign_i32() { let mut a: i32 = 5;