Constant time operations in the context of cryptography means that the runtime of the operation is not dependent on the data being manipulated.
As an example, suppose you were checking a 256-bit number for equality. This would be unacceptable:
bool eq256(uint32_t a[8], uint32_t b[8]) {
for (int i = 0; i < 8; ++i) {
if (a[i] != b[i]) return false;
}
return true;
}
Why? Because depending on the data this function takes longer or shorter, and timing attacks might be used to figure out secret data. Instead you need an implementation like this:
bool eq256(uint32_t a[8], uint32_t b[8]) {
uint32_t diff = 0;
for (int i = 0; i < 8; ++i) {
diff |= a[i] ^ b[i];
}
return diff == 0;
}
This implementation always takes the same amount of time regardless of the contents of a and b.
It goes further than this as well, you're not supposed to take branches based on secret data nor access memory locations based on secret data as those can be recovered through the branch predictor and cache respectively.