ct: Use volatile "trick" in all fe/scalar cmov implementations
Apparently clang 15 is able to compile our cmov code into a branch, at least for fe_cmov and fe_storage_cmov. This commit makes the condition volatile in all cmov implementations (except ge but that one only calls into the fe impls). This is just a quick fix. We should still look into other methods, e.g., asm and #457. We should also consider not caring about constant-time in scalar_low_impl.h We should also consider testing on very new compilers in nightly CI, see https://github.com/bitcoin-core/secp256k1/pull/864#issuecomment-769211867
This commit is contained in:
		
							parent
							
								
									464a9115b4
								
							
						
					
					
						commit
						4a496a36fb
					
				| @ -1147,8 +1147,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { | static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { | ||||||
|     uint32_t mask0, mask1; |     uint32_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); | ||||||
|     mask0 = flag + ~((uint32_t)0); |     mask0 = vflag + ~((uint32_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); |     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); | ||||||
|     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); |     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); | ||||||
| @ -1246,8 +1247,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { | static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { | ||||||
|     uint32_t mask0, mask1; |     uint32_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); | ||||||
|     mask0 = flag + ~((uint32_t)0); |     mask0 = vflag + ~((uint32_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); |     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); | ||||||
|     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); |     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); | ||||||
|  | |||||||
| @ -487,8 +487,9 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) { | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { | static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) { | ||||||
|     uint64_t mask0, mask1; |     uint64_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); | ||||||
|     mask0 = flag + ~((uint64_t)0); |     mask0 = vflag + ~((uint64_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); |     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); | ||||||
|     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); |     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); | ||||||
| @ -570,8 +571,9 @@ static SECP256K1_INLINE void secp256k1_fe_half(secp256k1_fe *r) { | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { | static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) { | ||||||
|     uint64_t mask0, mask1; |     uint64_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n)); | ||||||
|     mask0 = flag + ~((uint64_t)0); |     mask0 = vflag + ~((uint64_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); |     r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1); | ||||||
|     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); |     r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1); | ||||||
|  | |||||||
| @ -811,8 +811,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | ||||||
|     uint64_t mask0, mask1; |     uint64_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); | ||||||
|     mask0 = flag + ~((uint64_t)0); |     mask0 = vflag + ~((uint64_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); |     r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); | ||||||
|     r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); |     r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); | ||||||
|  | |||||||
| @ -632,8 +632,9 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | ||||||
|     uint32_t mask0, mask1; |     uint32_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d)); | ||||||
|     mask0 = flag + ~((uint32_t)0); |     mask0 = vflag + ~((uint32_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); |     r->d[0] = (r->d[0] & mask0) | (a->d[0] & mask1); | ||||||
|     r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); |     r->d[1] = (r->d[1] & mask0) | (a->d[1] & mask1); | ||||||
|  | |||||||
| @ -116,8 +116,9 @@ SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const | |||||||
| 
 | 
 | ||||||
| static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) { | ||||||
|     uint32_t mask0, mask1; |     uint32_t mask0, mask1; | ||||||
|  |     volatile int vflag = flag; | ||||||
|     SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r)); |     SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r)); | ||||||
|     mask0 = flag + ~((uint32_t)0); |     mask0 = vflag + ~((uint32_t)0); | ||||||
|     mask1 = ~mask0; |     mask1 = ~mask0; | ||||||
|     *r = (*r & mask0) | (*a & mask1); |     *r = (*r & mask0) | (*a & mask1); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user