[Cryptography] Implementing constant-time string comparison
ianG
iang at iang.org
Tue Jun 17 16:56:41 EDT 2014
On 17/06/2014 20:36 pm, sycamoreone wrote:
> Why are other libraries not doing this? That is, is this paranoid,
> or merely taking constant-time serious? Or does the 'unusual' return
> statement serve another purpose?
> http://codahale.com/a-lesson-in-timing-attacks/ suggested this
> Java implementation for Keyzar:
>
> public static boolean isEqual(byte[] a, byte[] b) {
> if (a.length != b.length) {
> return false;
> }
>
> int result = 0;
> for (int i = 0; i < a.length; i++) {
> result |= a[i] ^ b[i]
> }
> return result == 0;
> }
That's what I do. My code below, fwiw.
/**
* Constant Time Equality of two byte arrays.
*
* Constant time is only reliable to the extent that the arrays
* are of the same length.
* (It could be organised to be CT if one of them is null, but that
* seems like broken code to rely on such a thing, and any trickery
* might not survive the JIT.)
*
* @param one is a byte array of any length, else null
* @param two ditto
* @return true if the arrays are byte/bit-wise equal,
* true if both null, false if one only null,
* false if different lengths
* @see webfunds.util.Equals which is more comprehensive and
* adds noisy()
*/
public static final boolean ctEquals(final byte[] one, final byte[] two)
{
if (one == null && two == null) return true;
if (one == null || two == null) return false;
if (one.length != two.length) return false;
int xorDiffs = 0;
/*
* Run through the entire array(s), and XOR them to highlight
* any differing bits. This is the contant time bit.
*/
for (int i = 0; i < one.length; i++) {
xorDiffs |= ((int)(one[i] ^ two[i])) & 0xff;
}
/*
*
* Original NaCl C code turns any zero into -1, any bits into
* zero flipped those back to zero or -1 respectively,
* so a definition of 0==equals, -1==differs was returned.
* return (1 & (((int)diffBits - 1) >>> 8)) - 1;
* The problem with this is that we have to turn it into
* a boolean here, so the CT maths don't gain us anything,
* and even in C, the caller is likely to do the same thing...
*/
return 0 == xorDiffs ;
}
More information about the cryptography
mailing list