Eqaf
Eqaf - timing-safe comparison functions
In cryptography, a timing-attack is a side-channel attack in which the attacker attempts to compromise a cryptosystem by analyzing the time taken to execute cryptographic algorithms.
In some cases, a process needs to compare two values (input value and expected password). An attacker can analyze time needed by String
.compare/String
.equal to calculate expected password.
This side-channel attack is due implementation of String
.compare/String
.equal which leaves as soon as possible when it reachs a difference between a
and b
. By this way, time taken to compare two values differs if they are equal or not.
Distribution provides a little example of this kind of attack where we construct step by step (byte per byte) expected value from time spended to execute compare
.
Distribution wants to provide some functions which protect user against this kind of attack:
equal
like String
.equalcompare_be
like String
.comparecompare_le
which is a String
.compare with a reverse operation on inputsThese functions are tested to see how long they took to compare two equal values and two different values. See check tool for more informations.
equal a b
returns true
if a
and b
are equals. String.equal a b =
equal a b
for any a
and b
. The execution time of equal
depends solely on the length of the strings, not the contents.
compare_be a b
returns 0
if a
is equal to b
, a negative integer if a
if less (lexicographically) than b
, and a positive integer if a
is greater (lexicographically) than b
.
compare_be a b
returns the same order than String.compare a b
for any a
and b
(but not necessary the same integer!). Order is defined as:
compare_be a b < 0
means a < b
compare_be a b > 0
means a > b
compare_be a b = 0
means a = b
About time, if String.length a <> String.length b
, compare_be
does not look into a
or b
and no comparison in bytes will be done.
compare_be_with_len ~len a b
does compare_be a b
on len
bytes.
compare_le a b
is semantically compare_be (rev a) (rev b)
. With rev
reverses a string (a = rev (rev a)
).
compare_le_with_len a b
is semantically compare_be_with_len ~len (rev a)
(rev b)
. With rev
reverse a string (a = rev (rev a)
).
one_if_not_zero n
is a constant-time version of if n <> 0 then 1 else 0
. This is functionally equivalent to !!n
in the C programming language.
zero_if_not_zero n
is a constant-time of if n <> 0 then 0 else 1
. This is functionnaly equivalent to !n
in the C programming language.
select_int choose_b a b
is a
if choose_b = 0
and b
otherwise. This comparison is constant-time and it should not be possible for a measuring adversary to determine anything about the values of choose_b
, a
, or b
.
find_uint8 ?off ~f v
returns the index of the first occurrence which respects the predicate f
in string v
. Otherwise, it returns -1
.