Skip to content

Commit

Permalink
feat: add public ct_eq function
Browse files Browse the repository at this point in the history
  • Loading branch information
codahale committed Sep 28, 2023
1 parent 9c774e2 commit 07a65d1
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl Protocol {
self.process(&l_tag, Operation::AuthCrypt);

// Check the tag against the counterfactual short tag.
if ct_eq(s_tag, &s_tag_p) == 1 {
if ct_eq(s_tag, s_tag_p) == 1 {
// If the tag is verified, then the ciphertext is authentic. Return the slice of the
// input which contains the plaintext.
Some(in_out)
Expand Down Expand Up @@ -337,13 +337,18 @@ enum Operation {
Chain = 0x07,
}

/// A constant-time comparison using CMOV/CSEL instructions. Returns `1` if the two slices are
/// equal, `0` otherwise.
/// A constant-time comparison of two `u8` slices using conditional move instructions. Returns `1`
/// iff the two slices are equal, `0` otherwise.
#[inline(never)] // don't inline to avoid getting optimized into vartime
fn ct_eq(a: &[u8], b: &[u8]) -> u8 {
debug_assert_eq!(a.len(), b.len(), "both slices should be the same length");
pub fn ct_eq(a: impl AsRef<[u8]>, b: impl AsRef<[u8]>) -> u8 {
// Compare slice lengths in variable time, since there's no other way to do that.
if a.as_ref().len() != b.as_ref().len() {
return 0;
}

// Iterate through the value pairs, checking for inequality.
let mut res = 1;
for (x, y) in a.iter().zip(b.iter()) {
for (x, y) in a.as_ref().iter().zip(b.as_ref().iter()) {
x.cmovne(y, 0, &mut res);
}
res
Expand Down

0 comments on commit 07a65d1

Please sign in to comment.