Instantly share code, notes, and snippets.

# levigross/equality.clj

Last active Jan 13, 2020
Constant Time Comparison functions
 ; Taken from https://github.com/weavejester/crypto-equality/blob/master/src/crypto/equality.clj (ns crypto.equality "Securely test sequences of data for equality.") (defn eq? "Test whether two sequences of characters or bytes are equal in a way that protects against timing attacks. Note that this does not prevent an attacker from discovering the *length* of the data being compared." [a b] (let [a (map int a), b (map int b)] (if (and a b (= (count a) (count b))) (zero? (reduce bit-or (map bit-xor a b))) false)))
 #Taken from Django def constant_time_compare(val1, val2): """ Returns True if the two strings are equal, False otherwise. The time taken is independent of the number of characters that match. For the sake of simplicity, this function executes in constant time only when the two strings have the same length. It short-circuits when they have different lengths. """ if len(val1) != len(val2): return False result = 0 for x, y in zip(val1, val2): result |= ord(x) ^ ord(y) return result == 0
 #This is included within the stdlib in Py3k for an C alternative for Python 2.7.x see https://github.com/levigross/constant_time_compare/ from operator import _compare_digest as constant_time_compare # Or you can use this function taken from Django def constant_time_compare(val1, val2): """ Returns True if the two strings are equal, False otherwise. The time taken is independent of the number of characters that match. For the sake of simplicity, this function executes in constant time only when the two strings have the same length. It short-circuits when they have different lengths. """ if len(val1) != len(val2): return False result = 0 for x, y in zip(val1, val2): result |= x ^ y return result == 0
 import Data.Bits import Data.Char import Data.List import Data.Function -- Thank you Yan for this snippet constantTimeCompare a b = ((==) `on` length) a b && 0 == (foldl1 (.|.) joined) where joined = zipWith (xor `on` ord) a b
 // Taken from http://codahale.com/a-lesson-in-timing-attacks/ 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; }
 def secure_compare(a, b) return false if a.empty? || b.empty? || a.bytesize != b.bytesize l = a.unpack "C#{a.bytesize}" res = 0 b.each_byte { |byte| res |= byte ^ l.shift } res == 0 end

### tomato42 commented Aug 3, 2018

 The python code is not constant time in practice: https://securitypitfalls.wordpress.com/2018/08/03/constant-time-compare-in-python/