-
Notifications
You must be signed in to change notification settings - Fork 41
CBMC: Add and prove x86_64 backend contracts #1393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
mkannwischer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @willieyz - but the contracts need work. Please also make sure that the comments pointing to the specification are actually the correct files.
030bd4b to
348f68c
Compare
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
During #1393, we noticed that the HOL-Light proof for the x86 INTT proves the bound <=26632, while our contract requires <= 26631. This commit corrects the bound in the HOL-Light specification. Signed-off-by: Matthias J. Kannwischer <[email protected]>
87acd30 to
2d3d8be
Compare
mkannwischer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also add the contract and proof for rej_uniform (#1409)
7229fe3 to
98b01ad
Compare
2b60254 to
438ad7f
Compare
mkannwischer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @willieyz. Almost there.
6b47650 to
885467c
Compare
885467c to
d0bd799
Compare
mkannwischer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @willieyz for all that work! LGTM.
@hanno-becker, please take another look.
dev/x86_64/src/arith_native_x86_64.h
Outdated
| /* This must be kept in sync with the HOL-Light specification | ||
| * in proofs/hol_light/x86/proofs/mlkem_rej_uniform.ml. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add symmetric notes to all the x86 .ML proof scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @hanno-becker, thank you for the review.
Following your feedback, I have added symmetric notes to all .ML HOL-Light proofs that have corresponding CBMC proofs in mlkem/src/native/x86_64/src/arith_native_x86_64.h.
hanno-becker
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can't be completed because the HOL-Light spec for mulcache_compute is too weak. We need to fix this first.
@willieyz, can you remove the contract and proof for |
3ae93fb to
275c2b1
Compare
|
|
49fdcab to
483e42f
Compare
Hello, @hanno-becker , thank you for your help, I had rebase this PR on main, and add back the mulcache_compute's x86_64 backend contracts and proof |
483e42f to
369c78a
Compare
369c78a to
6444e81
Compare
| void mlk_nttfrombytes_avx2(int16_t *r, const uint8_t *a); | ||
| void mlk_nttfrombytes_avx2(int16_t *r, const uint8_t *a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to think about if/how we can capture alignment constraints.
Contrary to AArch64, 32-byte parameter alignment is mandatory for most of the AVX2 backend, and indeed part of the HOL-Light specs. However, we don't express this in the C signature, nor in the CBMC contract (and we probably can't).
dev/x86_64/src/arith_native_x86_64.h
Outdated
| void mlk_nttfrombytes_avx2(int16_t *r, const uint8_t *a); | ||
| void mlk_nttfrombytes_avx2(int16_t *r, const uint8_t *a) | ||
| /* This must be kept in sync with the HOL-Light specification in | ||
| * proofs/hol_light/x86/proofs/mlkem_frombytes.ml. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those paths need adjusting, it's x86_64 now
| requires(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q)) | ||
| assigns(memory_slice(r, sizeof(int16_t) * MLKEM_N)) | ||
| ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HOL-Light proof does not have any bounds requires/ensures clauses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't the HOL-LIght spec say the output is a permutation of the input?
That would imply that the bounds are maintained, wouldn't it?
- This commit introduces CBMC verification for several x86-64 optimized
assembly functions. The contracts for these functions are derived from
their corresponding HOL-Light correctness proofs.
- For each assembly function, a CBMC contract has been added to
`arith_native_x86_64.h`. Additionally, new proof harnesses have been
creat to formally verify that the generic C implementations (`*_native`)
correctly utilize these assembly backends and adhere to the top-level
API contracts.
- The following functions now have CBMC proofs based on their
HOL-Light specifications:
- polyvec_basemul_acc_montgomery_cached_asm_k2/k3/k4:
- Pre-conditions:
`<= &2 pow 12`(HOL_LIGHT) v.s. `MLKEM_UINT12_LIMIT + 1`(CBMC)
- Adds a CBMC pre-condition:
`requires(array_abs_bound(a, 0, 4 * MLKEM_N, MLKEM_UINT12_LIMIT +`
`1))`
- ntt_avx2:
- Pre-condition:
`<= &8191`(HOL_LIGHT) v.s. `8191 + 1`(CBMC)
- Post-condition:
`<= &23594`(HOL_LIGHT) v.s. `23594 + 1`(CBMC)
- Adds a CBMC pre-condition:
`requires(array_abs_bound(r, 0, MLKEM_N, 8192))`
- Adds a CBMC post-condition:
`ensures(array_abs_bound(r, 0, MLKEM_N, 23595))`
- intt_avx2:
- Post-condition:
`<= &26631` v.s. `26631 + 1`(CBMC)
- Adds a CBMC post-condition:
`ensures(array_abs_bound(r, 0, MLKEM_N, 26632))`
- reduce_avx2:
- Post-condition:
`< &3329`(HOL_LIGHT) v.s. `3329 == MLKEM_Q`(CBMC)
- Adds a CBMC post-condition:
`ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))`
- tobytes_avx2:
- Pre-condition:
`(!i. i < LENGTH l ==> val(EL i l) < 3329)`(HOL_LIGHT)
v.s.
`MLKEM_UINT12_LIMIT`(CBMC)
- Adds a CBMC pre-condition:
`requires(array_bound(a, 0, MLKEM_N, 0, MLKEM_Q))`
- frombytes_avx2:
- Post-conditions:
`read (memory :> bytes(a,dimindex(:32) * 12)) s0 =
num_of_wordlist (l:(12 word)list)`
- Adds a CBMC post-condition:
`ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_UINT12_LIMIT))`
- mlk_rej_uniform_asm:
- This proof are reference from aarch64 one, and change requires:
`requires(buflen % 24 == 0)` to `requires(buflen % 12 == 0)`
- mlk_tomont_avx2:
- Post conditions:
`(ival z_i == (tomont_3329 (ival o x)) i) (mod &3329) /\
abs(ival z_i) <= &3328)`
v.s.
`ensures(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q))`
- Add a CBMC post-condition:
`ensures(array_abs_bound(r, 0, MLKEM_N, 3328 + 1))`
- mlk_poly_mulcache_compute_avx2:
- Post conditions:
```
(ival zi == avx2_mulcache (ival o x) i) (mod &3329)) /\
(abs(ival zi) <= &3328))
```
v.s.
`ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))`
- Add a CBMC post-condition:
`ensures(array_abs_bound(out, 0, MLKEM_N/2, 3329))`
- mlk_nttunpack_avx2:
- Pre-condition:
`read(memory :> bytes(a, 512)) s =
num_of_wordlist (unpermute_list l)`
v.s.
`requires(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))`
- Post-condition:
`read(memory :> bytes(a, 512)) s =
num_of_wordlist (unpermute_list l)))`
v.s.
`ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))`
- Add CBMC pre-condition and post-condition:
`requires(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))`
`ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))`
Signed-off-by: willieyz <[email protected]>
Signed-off-by: willieyz <[email protected]>
6444e81 to
bc7522e
Compare
Resolves: CBMC: Prove that x86_64 backend fulfills native api.h contracts #1335
Rebased on x86_64 tomont_avx2: Remove unused qdata argument #1432, tomont isn't actually use mlk_qdata.
This PR also added proof corresponding these two hol-light: HOL-Light: Add x86 frombytes and tomont correctness proof #1418
This commit introduces CBMC verification for several x86-64 assembly functions. The contracts for these functions are derived from their corresponding HOL-Light correctness proofs.
The following functions now have CBMC proofs based on their
HOL-Light specifications:
polyvec_basemul_acc_montgomery_cached_asm_k2/k3/k4:
<= &2 pow 12(HOL_LIGHT) v.s.MLKEM_UINT12_LIMIT + 1(CBMC)requires(array_abs_bound(a, 0, 4 * MLKEM_N, MLKEM_UINT12_LIMIT +1))ntt_avx2:
<= &8191(HOL_LIGHT) v.s.8191 + 1(CBMC)<= &23594(HOL_LIGHT) v.s.23594 + 1(CBMC)requires(array_abs_bound(r, 0, MLKEM_N, 8192))ensures(array_abs_bound(r, 0, MLKEM_N, 23595))intt_avx2:
<= &26631v.s.26631 + 1(CBMC)ensures(array_abs_bound(r, 0, MLKEM_N, 26632))reduce_avx2:
< &3329(HOL_LIGHT) v.s.3329 == MLKEM_Q(CBMC)ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))tobytes_avx2:
(!i. i < LENGTH l ==> val(EL i l) < 3329)(HOL_LIGHT)v.s.
MLKEM_UINT12_LIMIT(CBMC)requires(array_bound(a, 0, MLKEM_N, 0, MLKEM_Q))frombytes_avx2:
read (memory :> bytes(a,dimindex(:32) * 12)) s0 = num_of_wordlist (l:(12 word)list)ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_UINT12_LIMIT))mlk_rej_uniform_asm:
requires(buflen % 24 == 0)torequires(buflen % 12 == 0)mlk_tomont_avx2:
(ival z_i == (tomont_3329 (ival o x)) i) (mod &3329) /\ abs(ival z_i) <= &3328)v.s.
ensures(array_abs_bound(r, 0, MLKEM_N, MLKEM_Q))ensures(array_abs_bound(r, 0, MLKEM_N, 3328 + 1))mlk_poly_mulcache_compute_avx2:
ensures(array_abs_bound(cache, 0, MLKEM_N/2, MLKEM_Q))Add a CBMC post-condition:
ensures(array_abs_bound(out, 0, MLKEM_N/2, 3329))mlk_nttunpack_avx2:
read(memory :> bytes(a, 512)) s = num_of_wordlist (unpermute_list l)))v.s.
requires(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))read(memory :> bytes(a, 512)) s = num_of_wordlist (unpermute_list l)))v.s.
ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))requires(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))ensures(array_bound(r, 0, MLKEM_N, 0, MLKEM_Q))