@@ -248,60 +248,6 @@ static inline crypto_word_t constant_time_msb_w(crypto_word_t a) {
248
248
return 0u - (a >> (sizeof (a ) * 8 - 1 ));
249
249
}
250
250
251
- // constant_time_lt_w returns 0xff..f if a < b and 0 otherwise.
252
- static inline crypto_word_t constant_time_lt_w (crypto_word_t a ,
253
- crypto_word_t b ) {
254
- // Consider the two cases of the problem:
255
- // msb(a) == msb(b): a < b iff the MSB of a - b is set.
256
- // msb(a) != msb(b): a < b iff the MSB of b is set.
257
- //
258
- // If msb(a) == msb(b) then the following evaluates as:
259
- // msb(a^((a^b)|((a-b)^a))) ==
260
- // msb(a^((a-b) ^ a)) == (because msb(a^b) == 0)
261
- // msb(a^a^(a-b)) == (rearranging)
262
- // msb(a-b) (because ∀x. x^x == 0)
263
- //
264
- // Else, if msb(a) != msb(b) then the following evaluates as:
265
- // msb(a^((a^b)|((a-b)^a))) ==
266
- // msb(a^(𝟙 | ((a-b)^a))) == (because msb(a^b) == 1 and 𝟙
267
- // represents a value s.t. msb(𝟙) = 1)
268
- // msb(a^𝟙) == (because ORing with 1 results in 1)
269
- // msb(b)
270
- //
271
- //
272
- // Here is an SMT-LIB verification of this formula:
273
- //
274
- // (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32)
275
- // (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a)))
276
- // )
277
- //
278
- // (declare-fun a () (_ BitVec 32))
279
- // (declare-fun b () (_ BitVec 32))
280
- //
281
- // (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b))))
282
- // (check-sat)
283
- // (get-model)
284
- return constant_time_msb_w (a ^((a ^b )|((a - b )^a )));
285
- }
286
-
287
- // constant_time_lt_8 acts like |constant_time_lt_w| but returns an 8-bit
288
- // mask.
289
- static inline uint8_t constant_time_lt_8 (crypto_word_t a , crypto_word_t b ) {
290
- return (uint8_t )(constant_time_lt_w (a , b ));
291
- }
292
-
293
- // constant_time_ge_w returns 0xff..f if a >= b and 0 otherwise.
294
- static inline crypto_word_t constant_time_ge_w (crypto_word_t a ,
295
- crypto_word_t b ) {
296
- return ~constant_time_lt_w (a , b );
297
- }
298
-
299
- // constant_time_ge_8 acts like |constant_time_ge_w| but returns an 8-bit
300
- // mask.
301
- static inline uint8_t constant_time_ge_8 (crypto_word_t a , crypto_word_t b ) {
302
- return (uint8_t )(constant_time_ge_w (a , b ));
303
- }
304
-
305
251
// constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise.
306
252
static inline crypto_word_t constant_time_is_zero_w (crypto_word_t a ) {
307
253
// Here is an SMT-LIB verification of this formula:
@@ -322,24 +268,12 @@ static inline crypto_word_t constant_time_is_nonzero_w(crypto_word_t a) {
322
268
return ~constant_time_is_zero_w (a );
323
269
}
324
270
325
- // constant_time_is_zero_8 acts like |constant_time_is_zero_w| but returns an
326
- // 8-bit mask.
327
- static inline uint8_t constant_time_is_zero_8 (crypto_word_t a ) {
328
- return (uint8_t )(constant_time_is_zero_w (a ));
329
- }
330
-
331
271
// constant_time_eq_w returns 0xff..f if a == b and 0 otherwise.
332
272
static inline crypto_word_t constant_time_eq_w (crypto_word_t a ,
333
273
crypto_word_t b ) {
334
274
return constant_time_is_zero_w (a ^ b );
335
275
}
336
276
337
- // constant_time_eq_8 acts like |constant_time_eq_w| but returns an 8-bit
338
- // mask.
339
- static inline uint8_t constant_time_eq_8 (crypto_word_t a , crypto_word_t b ) {
340
- return (uint8_t )(constant_time_eq_w (a , b ));
341
- }
342
-
343
277
// constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is all
344
278
// 1s or all 0s (as returned by the methods above), the select methods return
345
279
// either |a| (if |mask| is nonzero) or |b| (if |mask| is zero).
@@ -355,41 +289,6 @@ static inline crypto_word_t constant_time_select_w(crypto_word_t mask,
355
289
return (mask & a ) | (~mask & b );
356
290
}
357
291
358
- // constant_time_select_8 acts like |constant_time_select| but operates on
359
- // 8-bit values.
360
- static inline uint8_t constant_time_select_8 (crypto_word_t mask , uint8_t a ,
361
- uint8_t b ) {
362
- // |mask| is a word instead of |uint8_t| to avoid materializing 0x000..0MM
363
- // Making both |mask| and its value barrier |uint8_t| would allow the compiler
364
- // to materialize 0x????..?MM instead, but only clang is that clever.
365
- // However, vectorization of bitwise operations seems to work better on
366
- // |uint8_t| than a mix of |uint64_t| and |uint8_t|, so |m| is cast to
367
- // |uint8_t| after the value barrier but before the bitwise operations.
368
- uint8_t m = value_barrier_w (mask );
369
- return (m & a ) | (~m & b );
370
- }
371
-
372
- // constant_time_select_int acts like |constant_time_select| but operates on
373
- // ints.
374
- static inline int constant_time_select_int (crypto_word_t mask , int a , int b ) {
375
- return (int )(constant_time_select_w (mask , (crypto_word_t )(a ),
376
- (crypto_word_t )(b )));
377
- }
378
-
379
- // constant_time_conditional_memcpy copies |n| bytes from |src| to |dst| if
380
- // |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
381
- // ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
382
- static inline void constant_time_conditional_memcpy (void * dst , const void * src ,
383
- const size_t n ,
384
- const crypto_word_t mask ) {
385
- debug_assert_nonsecret (!buffers_alias (dst , n , src , n ));
386
- uint8_t * out = (uint8_t * )dst ;
387
- const uint8_t * in = (const uint8_t * )src ;
388
- for (size_t i = 0 ; i < n ; i ++ ) {
389
- out [i ] = constant_time_select_8 (mask , in [i ], out [i ]);
390
- }
391
- }
392
-
393
292
// constant_time_conditional_memxor xors |n| bytes from |src| to |dst| if
394
293
// |mask| is 0xff..ff and does nothing if |mask| is 0. The |n|-byte memory
395
294
// ranges at |dst| and |src| must not overlap, as when calling |memcpy|.
0 commit comments