pq-crystals / kyber

Other
782 stars 189 forks source link

Add a value barrier on the `cmov` control flag #55

Closed jschanck closed 1 year ago

jschanck commented 1 year ago

Peter and I were discussing whether it is safe to use boolean negation to produce the control flag for cmov, e.g.

  cmov(ss,kr,KYBER_SYMBYTES,!fail);

as he has done here. The risk is that the compiler may infer that !fail is 0/1 valued and then handle the two cases with a branch.

Crucially, this is only a problem if cmov can be inlined into decaps, and this can't happen given

But I'm worried that downstream consumers of this code might concatenate the source files before compilation.

The value barrier used here is the same countermeasure that BoringSSL used when clang started to recognize (mask & x) | (~mask & y) as selecting between x and y. For what it's worth, compilers don't (yet) seem to recognize x ^ (mask & (x ^ y)), or the pattern in avx2/verify.c, as selecting between x and y.