Skip to content

Commit 056f91d

Browse files
authored
Merge pull request #552 from pq-code-package/wconversion
Resolve -Wconversion and -Wsign-conversion warnings
2 parents 4da63d6 + 786e8f6 commit 056f91d

File tree

26 files changed

+309
-266
lines changed

26 files changed

+309
-266
lines changed

examples/basic/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ CFLAGS := \
5959
-Werror \
6060
-Wpointer-arith \
6161
-Wredundant-decls \
62+
-Wconversion \
63+
-Wsign-conversion \
6264
-Wno-long-long \
6365
-Wno-unknown-pragmas \
6466
-Wno-unused-command-line-argument \

mldsa/ct.h

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,67 @@ __contract__(ensures(return_value == b))
111111
}
112112
#endif /* MLD_USE_ASM_VALUE_BARRIER */
113113

114-
115-
/*
116-
* The mld_ct_sel_int32 function below makes deliberate use of unsigned
117-
* to signed integer conversion, which is implementation-defined
118-
* behaviour. Here, we assume that uint16_t -> int16_t is inverse
119-
* to int16_t -> uint16_t.
120-
*/
121114
#ifdef CBMC
122115
#pragma CPROVER check push
123116
#pragma CPROVER check disable "conversion"
124117
#endif
125118

119+
/*************************************************
120+
* Name: mld_cast_uint32_to_int32
121+
*
122+
* Description: Cast uint32 value to int32
123+
*
124+
* Returns: For uint32_t x, the unique y in int32_t
125+
* so that x == y mod 2^32.
126+
*
127+
* Concretely:
128+
* - x < 2^31: returns x
129+
* - x >= 2^31: returns x - 2^31
130+
*
131+
**************************************************/
132+
static MLD_ALWAYS_INLINE int32_t mld_cast_uint32_to_int32(uint32_t x)
133+
{
134+
/*
135+
* PORTABILITY: This relies on uint32_t -> int32_t
136+
* being implemented as the inverse of int32_t -> uint32_t,
137+
* which is implementation-defined (C99 6.3.1.3 (3))
138+
* CBMC (correctly) fails to prove this conversion is OK,
139+
* so we have to suppress that check here
140+
*/
141+
return (int32_t)x;
142+
}
143+
144+
#ifdef CBMC
145+
#pragma CPROVER check pop
146+
#endif
147+
148+
149+
/*************************************************
150+
* Name: mld_cast_int64_to_uint32
151+
*
152+
* Description: Cast int64 value to uint32 as per C standard.
153+
*
154+
* Returns: For int64_t x, the unique y in uint32_t
155+
* so that x == y mod 2^32.
156+
**************************************************/
157+
static MLD_ALWAYS_INLINE uint32_t mld_cast_int64_to_uint32(int64_t x)
158+
{
159+
return (uint32_t)(x & (int64_t)UINT32_MAX);
160+
}
161+
162+
/*************************************************
163+
* Name: mld_cast_int32_to_uint32
164+
*
165+
* Description: Cast int32 value to uint32 as per C standard.
166+
*
167+
* Returns: For int32_t x, the unique y in uint32_t
168+
* so that x == y mod 2^32.
169+
**************************************************/
170+
static MLD_ALWAYS_INLINE uint32_t mld_cast_int32_to_uint32(int32_t x)
171+
{
172+
return mld_cast_int64_to_uint32((int64_t)x);
173+
}
174+
126175
/*************************************************
127176
* Name: mld_ct_sel_int32
128177
*
@@ -137,35 +186,17 @@ __contract__(ensures(return_value == b))
137186
*
138187
**************************************************/
139188
static MLD_INLINE int32_t mld_ct_sel_int32(int32_t a, int32_t b, uint32_t cond)
140-
/* TODO: proof */
141189
__contract__(
142190
requires(cond == 0x0 || cond == 0xFFFFFFFF)
143191
ensures(return_value == (cond ? a : b))
144192
)
145193
{
146-
uint32_t au = a, bu = b;
194+
uint32_t au = mld_cast_int32_to_uint32(a);
195+
uint32_t bu = mld_cast_int32_to_uint32(b);
147196
uint32_t res = bu ^ (mld_value_barrier_u32(cond) & (au ^ bu));
148-
return (int32_t)res;
197+
return mld_cast_uint32_to_int32(res);
149198
}
150199

151-
/* Put unsigned-to-signed warnings in CBMC back into scope */
152-
#ifdef CBMC
153-
#pragma CPROVER check pop
154-
#endif
155-
156-
157-
158-
/*
159-
* The mld_ct_cmask_neg_i32 function below makes deliberate use of
160-
* signed to unsigned integer conversion, which is fully defined
161-
* behaviour in C. It is thus safe to disable this warning.
162-
*/
163-
#ifdef CBMC
164-
#pragma CPROVER check push
165-
#pragma CPROVER check disable "conversion"
166-
#endif
167-
168-
169200
/*************************************************
170201
* Name: mld_ct_cmask_neg_i32
171202
*
@@ -174,22 +205,16 @@ __contract__(
174205
* Arguments: int32_t x: Value to be converted into a mask
175206
*
176207
**************************************************/
177-
/* TODO: proof */
178208
static MLD_INLINE uint32_t mld_ct_cmask_neg_i32(int32_t x)
179209
__contract__(
180210
ensures(return_value == ((x < 0) ? 0xFFFFFFFF : 0))
181211
)
182212
{
183213
int64_t tmp = mld_value_barrier_i64((int64_t)x);
184214
tmp >>= 31;
185-
return (uint32_t)tmp;
215+
return mld_cast_int64_to_uint32(tmp);
186216
}
187217

188-
/* Put signed-to-unsigned warnings in CBMC back into scope */
189-
#ifdef CBMC
190-
#pragma CPROVER check pop
191-
#endif
192-
193218
/*************************************************
194219
* Name: mld_ct_abs_i32
195220
*
@@ -198,7 +223,6 @@ __contract__(
198223
* Arguments: int32_t x: Input value
199224
*
200225
**************************************************/
201-
/* TODO: proof */
202226
static MLD_INLINE int32_t mld_ct_abs_i32(int32_t x)
203227
__contract__(
204228
requires(x >= -INT32_MAX)

mldsa/fips202/fips202.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,12 @@ __contract__(
9494
mld_keccakf1600_permute(s);
9595
pos = 0;
9696
}
97-
mld_keccakf1600_xor_bytes(s, in, pos, inlen);
97+
/* Safety: At this point, inlen < r, so the truncation to unsigned is safe. */
98+
mld_keccakf1600_xor_bytes(s, in, pos, (unsigned)inlen);
9899

99-
return pos + inlen;
100+
/* Safety: At this point, inlen < r and pos <= r so the truncation to unsigned
101+
* is safe. */
102+
return (unsigned)(pos + inlen);
100103
}
101104

102105
/*************************************************
@@ -177,7 +180,8 @@ __contract__(
177180
mld_keccakf1600_permute(s);
178181
pos = 0;
179182
}
180-
i = bytes_to_go < r - pos ? bytes_to_go : r - pos;
183+
/* Safety: If bytes_to_go < r - pos, truncation to unsigned is safe. */
184+
i = bytes_to_go < r - pos ? (unsigned)bytes_to_go : r - pos;
181185
mld_keccakf1600_extract_bytes(s, out + out_offset, pos, i);
182186
bytes_to_go -= i;
183187
pos += i;

mldsa/fips202/fips202x4.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,21 @@ __contract__(
5353
inlen -= r;
5454
}
5555

56+
/* Safety: At this point, inlen < r, so the truncations to unsigned are safe
57+
* below. */
5658
if (inlen > 0)
5759
{
58-
mld_keccakf1600x4_xor_bytes(s, in0, in1, in2, in3, 0, inlen);
60+
mld_keccakf1600x4_xor_bytes(s, in0, in1, in2, in3, 0, (unsigned)inlen);
5961
}
6062

6163
if (inlen == r - 1)
6264
{
6365
p |= 128;
64-
mld_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, inlen, 1);
66+
mld_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, (unsigned)inlen, 1);
6567
}
6668
else
6769
{
68-
mld_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, inlen, 1);
70+
mld_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, (unsigned)inlen, 1);
6971
p = 128;
7072
mld_keccakf1600x4_xor_bytes(s, &p, &p, &p, &p, r - 1, 1);
7173
}

mldsa/native/aarch64/meta.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,16 @@ static MLD_INLINE int mld_rej_uniform_native(int32_t *r, unsigned len,
5454
{
5555
return -1;
5656
}
57+
58+
/* Safety: outlen is at most MLDSA_N, hence, this cast is safe. */
5759
return (int)mld_rej_uniform_asm(r, buf, buflen, mld_rej_uniform_table);
5860
}
5961

6062
static MLD_INLINE int mld_rej_uniform_eta2_native(int32_t *r, unsigned len,
6163
const uint8_t *buf,
6264
unsigned buflen)
6365
{
64-
int outlen;
66+
unsigned int outlen;
6567
/* AArch64 implementation assumes specific buffer lengths */
6668
if (len != MLDSA_N || buflen != MLD_AARCH64_REJ_UNIFORM_ETA2_BUFLEN)
6769
{
@@ -75,17 +77,17 @@ static MLD_INLINE int mld_rej_uniform_eta2_native(int32_t *r, unsigned len,
7577
* We declassify prior the input data and mark the outputs as secret.
7678
*/
7779
MLD_CT_TESTING_DECLASSIFY(buf, buflen);
78-
outlen =
79-
(int)mld_rej_uniform_eta2_asm(r, buf, buflen, mld_rej_uniform_eta_table);
80+
outlen = mld_rej_uniform_eta2_asm(r, buf, buflen, mld_rej_uniform_eta_table);
8081
MLD_CT_TESTING_SECRET(r, sizeof(int32_t) * outlen);
81-
return outlen;
82+
/* Safety: outlen is at most MLDSA_N and, hence, this cast is safe. */
83+
return (int)outlen;
8284
}
8385

8486
static MLD_INLINE int mld_rej_uniform_eta4_native(int32_t *r, unsigned len,
8587
const uint8_t *buf,
8688
unsigned buflen)
8789
{
88-
int outlen;
90+
unsigned int outlen;
8991
/* AArch64 implementation assumes specific buffer lengths */
9092
if (len != MLDSA_N || buflen != MLD_AARCH64_REJ_UNIFORM_ETA4_BUFLEN)
9193
{
@@ -99,10 +101,10 @@ static MLD_INLINE int mld_rej_uniform_eta4_native(int32_t *r, unsigned len,
99101
* We declassify prior the input data and mark the outputs as secret.
100102
*/
101103
MLD_CT_TESTING_DECLASSIFY(buf, buflen);
102-
outlen =
103-
(int)mld_rej_uniform_eta4_asm(r, buf, buflen, mld_rej_uniform_eta_table);
104+
outlen = mld_rej_uniform_eta4_asm(r, buf, buflen, mld_rej_uniform_eta_table);
104105
MLD_CT_TESTING_SECRET(r, sizeof(int32_t) * outlen);
105-
return outlen;
106+
/* Safety: outlen is at most MLDSA_N and, hence, this cast is safe. */
107+
return (int)outlen;
106108
}
107109

108110
static MLD_INLINE void mld_poly_decompose_32_native(int32_t *a1, int32_t *a0,

mldsa/native/aarch64/src/polyz_unpack_table.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
/* Table of indices used for tbl instructions in polyz_unpack_{17,19}. */
1515

1616
MLD_ALIGN const uint8_t mld_polyz_unpack_17_indices[] = {
17-
0, 1, 2, -1, 2, 3, 4, -1, 4, 5, 6, -1, 6, 7, 8, -1,
18-
9, 10, 11, -1, 11, 12, 13, -1, 13, 14, 15, -1, 15, 16, 17, -1,
19-
2, 3, 4, -1, 4, 5, 6, -1, 6, 7, 8, -1, 8, 9, 10, -1,
20-
11, 12, 13, -1, 13, 14, 15, -1, 15, 16, 17, -1, 17, 18, 19, -1,
17+
0, 1, 2, 255, 2, 3, 4, 255, 4, 5, 6, 255, 6, 7, 8, 255,
18+
9, 10, 11, 255, 11, 12, 13, 255, 13, 14, 15, 255, 15, 16, 17, 255,
19+
2, 3, 4, 255, 4, 5, 6, 255, 6, 7, 8, 255, 8, 9, 10, 255,
20+
11, 12, 13, 255, 13, 14, 15, 255, 15, 16, 17, 255, 17, 18, 19, 255,
2121
};
2222

2323
MLD_ALIGN const uint8_t mld_polyz_unpack_19_indices[] = {
24-
0, 1, 2, -1, 2, 3, 4, -1, 5, 6, 7, -1, 7, 8, 9, -1,
25-
10, 11, 12, -1, 12, 13, 14, -1, 15, 16, 17, -1, 17, 18, 19, -1,
26-
4, 5, 6, -1, 6, 7, 8, -1, 9, 10, 11, -1, 11, 12, 13, -1,
27-
14, 15, 16, -1, 16, 17, 18, -1, 19, 20, 21, -1, 21, 22, 23, -1,
24+
0, 1, 2, 255, 2, 3, 4, 255, 5, 6, 7, 255, 7, 8, 9, 255,
25+
10, 11, 12, 255, 12, 13, 14, 255, 15, 16, 17, 255, 17, 18, 19, 255,
26+
4, 5, 6, 255, 6, 7, 8, 255, 9, 10, 11, 255, 11, 12, 13, 255,
27+
14, 15, 16, 255, 16, 17, 18, 255, 19, 20, 21, 255, 21, 22, 23, 255,
2828
};
2929

3030
#else /* MLD_ARITH_BACKEND_AARCH64 && !MLD_CONFIG_MULTILEVEL_NO_SHARED */

mldsa/native/x86_64/meta.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ static MLD_INLINE int mld_rej_uniform_native(int32_t *r, unsigned len,
5959
return -1;
6060
}
6161

62+
/* Safety: outlen is at most MLDSA_N and, hence, this cast is safe. */
6263
return (int)mld_rej_uniform_avx2(r, buf);
6364
}
6465

6566
static MLD_INLINE int mld_rej_uniform_eta2_native(int32_t *r, unsigned len,
6667
const uint8_t *buf,
6768
unsigned buflen)
6869
{
69-
int outlen;
70+
unsigned int outlen;
7071
/* AVX2 implementation assumes specific buffer lengths */
7172
if (len != MLDSA_N || buflen != MLD_AVX2_REJ_UNIFORM_ETA2_BUFLEN)
7273
{
@@ -81,16 +82,17 @@ static MLD_INLINE int mld_rej_uniform_eta2_native(int32_t *r, unsigned len,
8182
* We declassify prior the input data and mark the outputs as secret.
8283
*/
8384
MLD_CT_TESTING_DECLASSIFY(buf, buflen);
84-
outlen = (int)mld_rej_uniform_eta2_avx2(r, buf);
85+
outlen = mld_rej_uniform_eta2_avx2(r, buf);
8586
MLD_CT_TESTING_SECRET(r, sizeof(int32_t) * outlen);
86-
return outlen;
87+
/* Safety: outlen is at most MLDSA_N and, hence, this cast is safe. */
88+
return (int)outlen;
8789
}
8890

8991
static MLD_INLINE int mld_rej_uniform_eta4_native(int32_t *r, unsigned len,
9092
const uint8_t *buf,
9193
unsigned buflen)
9294
{
93-
int outlen;
95+
unsigned int outlen;
9496
/* AVX2 implementation assumes specific buffer lengths */
9597
if (len != MLDSA_N || buflen != MLD_AVX2_REJ_UNIFORM_ETA4_BUFLEN)
9698
{
@@ -105,9 +107,10 @@ static MLD_INLINE int mld_rej_uniform_eta4_native(int32_t *r, unsigned len,
105107
* We declassify prior the input data and mark the outputs as secret.
106108
*/
107109
MLD_CT_TESTING_DECLASSIFY(buf, buflen);
108-
outlen = (int)mld_rej_uniform_eta4_avx2(r, buf);
110+
outlen = mld_rej_uniform_eta4_avx2(r, buf);
109111
MLD_CT_TESTING_SECRET(r, sizeof(int32_t) * outlen);
110-
return outlen;
112+
/* Safety: outlen is at most MLDSA_N and, hence, this cast is safe. */
113+
return (int)outlen;
111114
}
112115

113116
static MLD_INLINE void mld_poly_decompose_32_native(int32_t *a1, int32_t *a0,

mldsa/native/x86_64/src/poly_chknorm_avx2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ uint32_t mld_poly_chknorm_avx2(const __m256i *a, int32_t B)
4141
t = _mm256_or_si256(t, f);
4242
}
4343

44-
return _mm256_testz_si256(t, t) - 1;
44+
return (uint32_t)(_mm256_testz_si256(t, t) - 1);
4545
}
4646

4747
#else /* MLD_ARITH_BACKEND_X86_64_DEFAULT && !MLD_CONFIG_MULTILEVEL_NO_SHARED \

mldsa/native/x86_64/src/rej_uniform_avx2.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ unsigned int mld_rej_uniform_avx2(
9393
pos += 24;
9494

9595
tmp = _mm256_sub_epi32(d, bound);
96-
good = _mm256_movemask_ps((__m256)tmp);
96+
good = (uint32_t)_mm256_movemask_ps((__m256)tmp);
9797
tmp = _mm256_cvtepu8_epi32(
9898
_mm_loadl_epi64((__m128i *)&mld_rej_uniform_table[good]));
9999
d = _mm256_permutevar8x32_epi32(d, tmp);
100100

101101
_mm256_storeu_si256((__m256i *)&r[ctr], d);
102-
ctr += _mm_popcnt_u32(good);
102+
ctr += (unsigned)_mm_popcnt_u32(good);
103103
}
104104

105105
while (ctr < MLDSA_N && pos <= MLD_AVX2_REJ_UNIFORM_BUFLEN - 3)
@@ -111,7 +111,8 @@ unsigned int mld_rej_uniform_avx2(
111111

112112
if (t < MLDSA_Q)
113113
{
114-
r[ctr++] = t;
114+
/* Safe because t < MLDSA_Q. */
115+
r[ctr++] = (int32_t)t;
115116
}
116117
}
117118

0 commit comments

Comments
 (0)