Skip to content

Commit da00d50

Browse files
hanno-beckermkannwischer
authored andcommitted
HOL-Light: Prove output bound for mulcache computation
This commit strengthens the HOL-Light spec for poly_mulcache_compute to include the absolute value bound by MLKEM_Q. The CBMC specs for the native backend are adjusted accordingly. Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
1 parent fa103d6 commit da00d50

File tree

5 files changed

+30
-19
lines changed

5 files changed

+30
-19
lines changed

dev/aarch64_clean/src/arith_native_aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ __contract__(
9393
requires(zetas == mlk_aarch64_zetas_mulcache_native)
9494
requires(zetas_twisted == mlk_aarch64_zetas_mulcache_twisted_native)
9595
assigns(object_whole(cache))
96+
ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))
9697
);
9798

9899
#define mlk_poly_tobytes_asm MLK_NAMESPACE(poly_tobytes_asm)

dev/aarch64_opt/src/arith_native_aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ __contract__(
9393
requires(zetas == mlk_aarch64_zetas_mulcache_native)
9494
requires(zetas_twisted == mlk_aarch64_zetas_mulcache_twisted_native)
9595
assigns(object_whole(cache))
96+
ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))
9697
);
9798

9899
#define mlk_poly_tobytes_asm MLK_NAMESPACE(poly_tobytes_asm)

mlkem/native/aarch64/src/arith_native_aarch64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ __contract__(
9393
requires(zetas == mlk_aarch64_zetas_mulcache_native)
9494
requires(zetas_twisted == mlk_aarch64_zetas_mulcache_twisted_native)
9595
assigns(object_whole(cache))
96+
ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))
9697
);
9798

9899
#define mlk_poly_tobytes_asm MLK_NAMESPACE(poly_tobytes_asm)

mlkem/native/api.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ __contract__(
209209
requires(memory_no_alias(cache, sizeof(int16_t) * (MLKEM_N / 2)))
210210
requires(memory_no_alias(mlk_poly, sizeof(int16_t) * MLKEM_N))
211211
assigns(object_whole(cache))
212+
ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))
212213
);
213214
#endif /* MLK_USE_NATIVE_POLY_MULCACHE_COMPUTE */
214215

proofs/hol_light/arm/proofs/mlkem_poly_mulcache_compute.ml

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ let poly_mulcache_compute_GOAL = `forall pc src dst zetas zetas_twisted x y retu
8383
read PC s = returnaddress /\
8484
// Odd coefficients have been multiplied with respective root of unity
8585
(!i. i < 128 ==> let z_i = read(memory :> bytes16(word_add dst (word (2 * i)))) s
86-
in (ival z_i == (mulcache (ival o x)) i) (mod &3329)))
86+
in (ival z_i == (mulcache (ival o x)) i) (mod &3329) /\
87+
abs(ival z_i) <= &3328))
8788
// Register and memory footprint
8889
(MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,,
8990
MAYCHANGE [memory :> bytes(dst, 256)])
@@ -144,30 +145,36 @@ let poly_mulcache_compute_SPEC = prove(poly_mulcache_compute_GOAL,
144145
(* Forget all assumptions *)
145146
POP_ASSUM_LIST (K ALL_TAC) THEN
146147

147-
(* Split into one congruence goals per index. *)
148-
REPEAT CONJ_TAC THEN
148+
(* Split into pairs of congruence and absolute value goals *)
149+
REPEAT(W(fun (asl,w) ->
150+
if length(conjuncts w) > 3 then CONJ_TAC else NO_TAC)) THEN
149151

150152
REWRITE_TAC[mulcache; mulcache_zetas_twisted; mulcache_zetas] THEN
151153
CONV_TAC(ONCE_DEPTH_CONV EL_CONV) THEN
152154

153155
(* Instantiate general congruence and bounds rule for Barrett multiplication
154156
* so it matches the current goal, and add as new assumption. *)
155-
W (MP_TAC o CONGBOUND_RULE o rand o lhand o rator o snd) THEN
157+
W (MP_TAC o CONGBOUND_RULE o rand o rand o rator o rator o lhand o snd) THEN
156158
ASM_REWRITE_TAC [o_THM] THEN
157159

158-
(* CONGBOUND_RULE gives a correctness and a bounds result -- here, we only
159-
* need the correctness result since poly_mulcache_compute makes no statement
160-
* about output coefficient bounds. *)
161-
MATCH_MP_TAC (TAUT `(x ==> z) ==> (x /\ y ==> z)`) THEN
162-
163-
REWRITE_TAC [GSYM INT_REM_EQ] THEN
164-
CONV_TAC INT_REM_DOWN_CONV THEN
165-
STRIP_TAC THEN ASM_REWRITE_TAC [] THEN
166-
CONV_TAC ((GEN_REWRITE_CONV ONCE_DEPTH_CONV [BITREVERSE7_CLAUSES])
167-
THENC (REPEATC (CHANGED_CONV (ONCE_DEPTH_CONV NUM_RED_CONV)))) THEN
168-
169-
REWRITE_TAC[INT_REM_EQ] THEN
170-
REWRITE_TAC [REAL_INT_CONGRUENCE; INT_OF_NUM_EQ; ARITH_EQ] THEN
171-
REWRITE_TAC[GSYM REAL_OF_INT_CLAUSES] THEN
172-
CONV_TAC(RAND_CONV REAL_POLY_CONV) THEN REAL_INTEGER_TAC
160+
MATCH_MP_TAC MONO_AND THEN (CONJ_TAC THENL [
161+
(* Correctness *)
162+
REWRITE_TAC [GSYM INT_REM_EQ; o_THM] THEN
163+
CONV_TAC INT_REM_DOWN_CONV THEN
164+
STRIP_TAC THEN ASM_REWRITE_TAC [] THEN
165+
CONV_TAC ((GEN_REWRITE_CONV ONCE_DEPTH_CONV [BITREVERSE7_CLAUSES])
166+
THENC (REPEATC (CHANGED_CONV (ONCE_DEPTH_CONV NUM_RED_CONV)))) THEN
167+
REWRITE_TAC[INT_REM_EQ] THEN
168+
REWRITE_TAC [REAL_INT_CONGRUENCE; INT_OF_NUM_EQ; ARITH_EQ] THEN
169+
REWRITE_TAC[GSYM REAL_OF_INT_CLAUSES] THEN
170+
CONV_TAC(RAND_CONV REAL_POLY_CONV) THEN REAL_INTEGER_TAC
171+
172+
;
173+
174+
(* Bounds *)
175+
REWRITE_TAC [INT_ABS_BOUNDS] THEN
176+
MATCH_MP_TAC(INT_ARITH
177+
`l':int <= l /\ u <= u'
178+
==> l <= x /\ x <= u ==> l' <= x /\ x <= u'`) THEN
179+
CONV_TAC INT_REDUCE_CONV])
173180
);;

0 commit comments

Comments
 (0)