@@ -283,22 +283,32 @@ byte[] kemDecrypt(MLKEMPrivateKeyParameters privateKey, byte[] cipherText)
283283
284284 byte [] cmp = indCpa .encrypt (publicKey , Arrays .copyOfRange (buf , 0 , KyberSymBytes ), Arrays .copyOfRange (kr , KyberSymBytes , kr .length ));
285285
286- boolean fail = !( Arrays . constantTimeAreEqual ( cipherText , cmp ) );
286+ int fail = constantTimeZeroOnEqual ( cipherText , cmp );
287287
288288 cmov (kr , implicit_rejection , KyberSymBytes , fail );
289289
290290 return Arrays .copyOfRange (kr , 0 , sessionKeyLength );
291291 }
292292
293- private void cmov (byte [] r , byte [] x , int xlen , boolean b )
293+ private void cmov (byte [] r , byte [] x , int xlen , int fail )
294294 {
295- if (b )
295+ int mask = (0 - fail ) >> 24 ;
296+
297+ for (int i = 0 ; i != xlen ; i ++)
296298 {
297- System . arraycopy ( x , 0 , r , 0 , xlen );
299+ r [ i ] = ( byte )(( x [ i ] & mask ) | ( r [ i ] & ~ mask ) );
298300 }
299- else
301+ }
302+
303+ private int constantTimeZeroOnEqual (byte [] input , byte [] expected )
304+ {
305+ int result = expected .length ^ input .length ;
306+
307+ for (int i = 0 ; i != expected .length ; i ++)
300308 {
301- System . arraycopy ( r , 0 , r , 0 , xlen ) ;
309+ result |= input [ i ] ^ expected [ i ] ;
302310 }
311+
312+ return result & 0xff ;
303313 }
304314}
0 commit comments