Skip to content

Commit a1ad592

Browse files
authored
Merge pull request #280 from pq-code-package/cbmc-poly_add-polyveck_add-polyvecl_add
CBMC and refactor: Change poly_add and vector-variants and add proof
2 parents 6edd5e9 + 7ba5f84 commit a1ad592

File tree

8 files changed

+65
-56
lines changed

8 files changed

+65
-56
lines changed

mldsa/poly.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@ void poly_caddq(poly *a)
5050

5151
mld_assert_bound(a->coeffs, MLDSA_N, 0, MLDSA_Q);
5252
}
53-
54-
void poly_add(poly *c, const poly *a, const poly *b)
53+
/* Reference: We use destructive version (output=first input) to avoid
54+
* reasoning about aliasing in the CBMC specification */
55+
void poly_add(poly *r, const poly *b)
5556
{
5657
unsigned int i;
57-
5858
for (i = 0; i < MLDSA_N; ++i)
5959
__loop__(
60-
invariant(i <= MLDSA_N)
61-
invariant(forall(k1, 0, i, c->coeffs[k1] == a->coeffs[k1] + b->coeffs[k1])))
60+
invariant(i <= MLDSA_N)
61+
invariant(forall(k0, i, MLDSA_N, r->coeffs[k0] == loop_entry(*r).coeffs[k0]))
62+
invariant(forall(k1, 0, i, r->coeffs[k1] == loop_entry(*r).coeffs[k1] + b->coeffs[k1]))
63+
)
6264
{
63-
c->coeffs[i] = a->coeffs[i] + b->coeffs[i];
65+
r->coeffs[i] = r->coeffs[i] + b->coeffs[i];
6466
}
65-
66-
cassert(forall(k, 0, MLDSA_N, c->coeffs[k] == a->coeffs[k] + b->coeffs[k]));
6767
}
6868

6969
void poly_sub(poly *c, const poly *a, const poly *b)

mldsa/poly.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,23 @@ __contract__(
5757
*
5858
* Description: Add polynomials. No modular reduction is performed.
5959
*
60-
* Arguments: - poly *c: pointer to output polynomial
61-
* - const poly *a: pointer to first summand
62-
* - const poly *b: pointer to second summand
60+
* Arguments: - r: Pointer to input-output polynomial to be added to.
61+
* - b: Pointer to input polynomial that should be added
62+
* to r. Must be disjoint from r.
6363
**************************************************/
64-
void poly_add(poly *c, const poly *a, const poly *b)
64+
65+
/*
66+
* NOTE: The reference implementation uses a 3-argument poly_add.
67+
* We specialize to the accumulator form to avoid reasoning about aliasing.
68+
*/
69+
void poly_add(poly *r, const poly *b)
6570
__contract__(
66-
requires(memory_no_alias(c, sizeof(poly)))
67-
requires(memory_no_alias(a, sizeof(poly)))
6871
requires(memory_no_alias(b, sizeof(poly)))
69-
requires(forall(k0, 0, MLDSA_N, (int64_t) a->coeffs[k0] + b->coeffs[k0] <= INT32_MAX))
70-
requires(forall(k1, 0, MLDSA_N, (int64_t) a->coeffs[k1] + b->coeffs[k1] >= INT32_MIN))
71-
assigns(memory_slice(c, sizeof(poly)))
72+
requires(memory_no_alias(r, sizeof(poly)))
73+
requires(forall(k0, 0, MLDSA_N, (int64_t) r->coeffs[k0] + b->coeffs[k0] <= INT32_MAX))
74+
requires(forall(k1, 0, MLDSA_N, (int64_t) r->coeffs[k1] + b->coeffs[k1] >= INT32_MIN))
75+
assigns(memory_slice(r, sizeof(poly)))
76+
ensures(forall(k, 0, MLDSA_N, r->coeffs[k] == old(*r).coeffs[k] + b->coeffs[k]))
7277
);
7378

7479
#define poly_sub MLD_NAMESPACE(poly_sub)

mldsa/polyvec.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,24 @@ void polyvecl_reduce(polyvecl *v)
162162
}
163163
}
164164

165-
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v)
165+
/* Reference: We use destructive version (output=first input) to avoid
166+
* reasoning about aliasing in the CBMC specification */
167+
void polyvecl_add(polyvecl *u, const polyvecl *v)
166168
{
167169
unsigned int i;
168170

169171
for (i = 0; i < MLDSA_L; ++i)
170172
__loop__(
171-
invariant(i <= MLDSA_L))
173+
invariant(i <= MLDSA_L)
174+
invariant(forall(k0, i, MLDSA_L,
175+
forall(k1, 0, MLDSA_N, u->vec[k0].coeffs[k1] == loop_entry(*u).vec[k0].coeffs[k1]))))
172176
{
173-
poly t;
174-
poly_add(&t, &u->vec[i], &v->vec[i]);
177+
poly tmp = u->vec[i];
178+
poly_add(&tmp, &v->vec[i]);
175179
/* Full struct assignment from local variables to simplify proof */
176180
/* TODO: eliminate once CBMC resolves
177181
* https://github.com/diffblue/cbmc/issues/8617 */
178-
w->vec[i] = t;
182+
u->vec[i] = tmp;
179183
}
180184
}
181185

@@ -323,20 +327,24 @@ void polyveck_caddq(polyveck *v)
323327
}
324328
}
325329

326-
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v)
330+
/* Reference: We use destructive version (output=first input) to avoid
331+
* reasoning about aliasing in the CBMC specification */
332+
void polyveck_add(polyveck *u, const polyveck *v)
327333
{
328334
unsigned int i;
329335

330336
for (i = 0; i < MLDSA_K; ++i)
331337
__loop__(
332-
invariant(i <= MLDSA_K))
338+
invariant(i <= MLDSA_K)
339+
invariant(forall(k0, i, MLDSA_K,
340+
forall(k1, 0, MLDSA_N, u->vec[k0].coeffs[k1] == loop_entry(*u).vec[k0].coeffs[k1]))))
333341
{
334-
poly t;
335-
poly_add(&t, &u->vec[i], &v->vec[i]);
342+
poly tmp = u->vec[i];
343+
poly_add(&tmp, &v->vec[i]);
336344
/* Full struct assignment from local variables to simplify proof */
337345
/* TODO: eliminate once CBMC resolves
338346
* https://github.com/diffblue/cbmc/issues/8617 */
339-
w->vec[i] = t;
347+
u->vec[i] = tmp;
340348
}
341349
}
342350

mldsa/polyvec.h

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,18 @@ __contract__(
6767
* Description: Add vectors of polynomials of length MLDSA_L.
6868
* No modular reduction is performed.
6969
*
70-
* Arguments: - polyvecl *w: pointer to output vector
71-
* - const polyvecl *u: pointer to first summand
72-
* - const polyvecl *v: pointer to second summand
70+
* Arguments: - polyveck *u: pointer to input-output vector of polynomials to
71+
* be added to
72+
* - const polyveck *v: pointer to second input vector of
73+
* polynomials
7374
**************************************************/
74-
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v)
75+
void polyvecl_add(polyvecl *u, const polyvecl *v)
7576
__contract__(
76-
requires(memory_no_alias(w, sizeof(polyvecl)))
7777
requires(memory_no_alias(u, sizeof(polyvecl)))
7878
requires(memory_no_alias(v, sizeof(polyvecl)))
79-
requires(forall(k0, 0, MLDSA_L,
80-
forall(k1, 0, MLDSA_N, (int64_t) u->vec[k0].coeffs[k1] + v->vec[k0].coeffs[k1] <= INT32_MAX)))
81-
requires(forall(k2, 0, MLDSA_L,
82-
forall(k3, 0, MLDSA_N, (int64_t) u->vec[k2].coeffs[k3] + v->vec[k2].coeffs[k3] >= INT32_MIN)))
83-
assigns(memory_slice(w, sizeof(polyvecl)))
79+
requires(forall(k0, 0, MLDSA_L, forall(k1, 0, MLDSA_N, (int64_t) u->vec[k0].coeffs[k1] + v->vec[k0].coeffs[k1] <= INT32_MAX)))
80+
requires(forall(k2, 0, MLDSA_L, forall(k3, 0, MLDSA_N, (int64_t) u->vec[k2].coeffs[k3] + v->vec[k2].coeffs[k3] >= INT32_MIN)))
81+
assigns(object_whole(u))
8482
);
8583

8684
#define polyvecl_ntt MLD_NAMESPACE(polyvecl_ntt)
@@ -242,20 +240,18 @@ __contract__(
242240
* Description: Add vectors of polynomials of length MLDSA_K.
243241
* No modular reduction is performed.
244242
*
245-
* Arguments: - polyveck *w: pointer to output vector
246-
* - const polyveck *u: pointer to first summand
247-
* - const polyveck *v: pointer to second summand
243+
* Arguments: - polyveck *u: pointer to input-output vector of polynomials to
244+
* be added to
245+
* - const polyveck *v: pointer to second input vector of
246+
* polynomials
248247
**************************************************/
249-
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v)
248+
void polyveck_add(polyveck *u, const polyveck *v)
250249
__contract__(
251-
requires(memory_no_alias(w, sizeof(polyveck)))
252250
requires(memory_no_alias(u, sizeof(polyveck)))
253251
requires(memory_no_alias(v, sizeof(polyveck)))
254-
requires(forall(k0, 0, MLDSA_K,
255-
forall(k1, 0, MLDSA_N, (int64_t) u->vec[k0].coeffs[k1] + v->vec[k0].coeffs[k1] <= INT32_MAX)))
256-
requires(forall(k2, 0, MLDSA_K,
257-
forall(k3, 0, MLDSA_N, (int64_t) u->vec[k2].coeffs[k3] + v->vec[k2].coeffs[k3] >= INT32_MIN)))
258-
assigns(memory_slice(w, sizeof(polyveck)))
252+
requires(forall(k0, 0, MLDSA_K, forall(k1, 0, MLDSA_N, (int64_t) u->vec[k0].coeffs[k1] + v->vec[k0].coeffs[k1] <= INT32_MAX)))
253+
requires(forall(k2, 0, MLDSA_K, forall(k3, 0, MLDSA_N, (int64_t) u->vec[k2].coeffs[k3] + v->vec[k2].coeffs[k3] >= INT32_MIN)))
254+
assigns(object_whole(u))
259255
);
260256

261257
#define polyveck_sub MLD_NAMESPACE(polyveck_sub)

mldsa/sign.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ int crypto_sign_keypair_internal(uint8_t *pk, uint8_t *sk,
7171
polyveck_invntt_tomont(&t1);
7272

7373
/* Add error vector s2 */
74-
polyveck_add(&t1, &t1, &s2);
74+
polyveck_add(&t1, &s2);
7575

7676
/* Extract t1 and write public key */
7777
polyveck_caddq(&t1);
@@ -179,7 +179,7 @@ int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
179179
/* Compute z, reject if it reveals secret */
180180
polyvecl_pointwise_poly_montgomery(&z, &cp, &s1);
181181
polyvecl_invntt_tomont(&z);
182-
polyvecl_add(&z, &z, &y);
182+
polyvecl_add(&z, &y);
183183
polyvecl_reduce(&z);
184184
if (polyvecl_chknorm(&z, MLDSA_GAMMA1 - MLDSA_BETA))
185185
{
@@ -209,7 +209,7 @@ int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
209209
continue;
210210
}
211211

212-
polyveck_add(&w0, &w0, &h);
212+
polyveck_add(&w0, &h);
213213
n = polyveck_make_hint(&h, &w0, &w1);
214214
if (n > MLDSA_OMEGA)
215215
{

proofs/cbmc/poly_add/poly_add_harness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
void harness(void)
77
{
8-
poly *c, *a, *b;
9-
poly_add(c, a, b);
8+
poly *r, *b;
9+
poly_add(r, b);
1010
}

proofs/cbmc/polyveck_add/polyveck_add_harness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
void harness(void)
77
{
8-
polyveck *a, *b, *c;
9-
polyveck_add(a, b, c);
8+
polyveck *r, *b;
9+
polyveck_add(r, b);
1010
}

proofs/cbmc/polyvecl_add/polyvecl_add_harness.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
void harness(void)
77
{
8-
polyvecl *a, *b, *c;
9-
polyvecl_add(a, b, c);
8+
polyvecl *r, *b;
9+
polyvecl_add(r, b);
1010
}

0 commit comments

Comments
 (0)