For most platforms, this isgenerates code free from data-dependent timing variation¹. I know no exception, but still that should be checked, e.g. by inspection of the generated code, and in theory invoking/verifying considerations about what influences the execution time of an instruction on each of the target CPUs.
On many platforms, mult1B_fast
(perhaps, made inline
) is close to the fastest portable constant-time C code free from data-dependent timing variation. However, especially on CPUs lacking a barrel shifter, it may be worth trying the mult1B_shift8
variation, which only shifts by a whole byte: the above technique is applied on the high byte 16-bit variables, hence & 1
becomes &256
. Assembly language often allows further gain, including thanks to direct access to the carry bit.
Note: Silence any bogusBogus compiler/tool warning on the tune of unary«unary minus operator applied to unsigned type, result still unsignedunsigned» can be silenced, perhaps by changing the occurrences of -(
to 0-(
. Add parenthesis to satisfy any requiredenforced convention.
No, because full field multiplication is not necessary (also see note¹). Except for computation of the S-box, a natural implementation of AES encryption² (including AES decryption in CTR mode) only needs field multiplication by 2the field element $x$, encoded 2
. Using the same technique as above, that can be coded as one of:
inline uint8_t double1Bmul1B_x(uint8_t a) {
return (-(a>>7) & 0x1B) ^ (a+a);
}
inline uint8_t double1B_shift8mul1B_x_shift8(uint8_t a) {
uint16_t r = a+a;
return ((-(r & 256))>>8 & 0x1B) ^ r;
}
² One such natural implementation is there. It is typically free from data-dependent timing variation on CPUs without a data cache when the two 256-byte tables are aligned to a 256-byte boundary. One of these tables is replaceable by double1Bmul1B_x
, the other is the S-box.