Despite the frequent claims that Ed25519 is more secure against side-channel attacks than (for instance) signatures performed over NIST P-256, I noticed that most implementations (including the original submissions) rely on table look-ups performed with secret index to achieve high performance.
That is notoriously a big no-no, but I see that concerns are waived due to the use of conditional move constructions.
For instance, the fundamental construct is often:
void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
{
int i;
crypto_uint32 mask = b;
mask = -mask;
for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
}
where mask
is either all 1s or all 0s.
I am not totally convinced by this construction.
For instance, when implemented in C, what are the chances that the compiler deobfuscate this into a branch?
For an assembly implementation, what is the chance that XOR by a mask depends on the number of 1s set in the mask?
Is safe to use this approach beyond Ed25519?
b
contains a secret bit, and the goal of this specific function is to leaver->v
with the value it has or the value ofx->v
. It is commonly seen in Ed25519 code for windowed multiplication of a fixed secret scalar by a fixed-point. $\endgroup$b
has no effect on which indices are accessed nor what order they are accessed in. There are no table lookups based onb
. $\endgroup$