Or rather, it accelerates a dictionary attack from O(sizeof(dictionary)) tries to O(length(hash)) tries.
(Let's suppose you are comparing by hex digits. You try 16 dictionary "words" whose hashes start with 0...f. One of those should take slightly longer. You then try 16 dictionary "words" whose hashes start with the digit found previously with different second digits. (Skip any digits that you don't have a word for.) One of those should take slightly longer... Repeat until found.)
This can be mitigated with a salt - if and only if you manage to prevent the user from figuring out how your salting scheme works.
Something like this should work:
/* Swap char for uint<register_size> for speed */
#define CMP_TYPE char
/* Assuming char* sha256(char* input); */
CMP_TYPE* input_hash=(CMP_TYPE*) sha256(input);
CMP_TYPE* token_hash=(CMP_TYPE*) sha256(token); /* Precomputed? */
/* max_pos=32 for char on most systems */
int max_pos=256 >> (3 + sizeof(CMP_TYPE));
char cmp=0;
for (int i=0;i<max_pos;i++) {
cmp = cmp | (token_hash[i] ^ input_hash[i]);
}
return (cmp != 0);
The reason for the CMP_TYPE #define is so that you can optimise the comparison by replacing char with uint32 or uint64.For instance, it's legal for the compiler to insert a strcmp fallthrough (`if input == token: return true`, or rather the strcmp equivalent) at the start, I'm pretty sure.
For one thing, you have to assume that the SHA function is data-independent time (which, again, good luck doing in C / C++).
For another thing, noise in timing attacks doesn't prevent them. Even at levels of noise that seemingly obscure everything. And it's a very bad thing to rely on network latency being unpredictable enough.
b) There is no SHA algorithm in the C / C++ standard library (that I know of), muchless a guaranteed constant-time (or rather, data-independent) one.
c) The compiler is well within its rights to insert "busy_loop_for_ms(input_char);" anywhere it wishes. It is unlikely to do so, but it is allowed to. As I said: C and C++ don't have any notion of constant or variable time.