-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathcbmc.h
142 lines (118 loc) · 4.87 KB
/
cbmc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright (c) 2024-2025 The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef MLK_CBMC_H
#define MLK_CBMC_H
/***************************************************
* Basic replacements for __CPROVER_XXX contracts
***************************************************/
#include "common.h"
#ifndef CBMC
#define __contract__(x)
#define __loop__(x)
#else /* CBMC _is_ defined, therefore we're doing proof */
#define __contract__(x) x
#define __loop__(x) x
/* https://diffblue.github.io/cbmc/contracts-assigns.html */
#define assigns(...) __CPROVER_assigns(__VA_ARGS__)
/* https://diffblue.github.io/cbmc/contracts-requires-ensures.html */
#define requires(...) __CPROVER_requires(__VA_ARGS__)
#define ensures(...) __CPROVER_ensures(__VA_ARGS__)
/* https://diffblue.github.io/cbmc/contracts-loops.html */
#define invariant(...) __CPROVER_loop_invariant(__VA_ARGS__)
#define decreases(...) __CPROVER_decreases(__VA_ARGS__)
/* cassert to avoid confusion with in-built assert */
#define cassert(x) __CPROVER_assert(x, "cbmc assertion failed")
#define assume(...) __CPROVER_assume(__VA_ARGS__)
/***************************************************
* Macros for "expression" forms that may appear
* _inside_ top-level contracts.
***************************************************/
/*
* function return value - useful inside ensures
* https://diffblue.github.io/cbmc/contracts-functions.html
*/
#define return_value (__CPROVER_return_value)
/*
* assigns l-value targets
* https://diffblue.github.io/cbmc/contracts-assigns.html
*/
#define object_whole(...) __CPROVER_object_whole(__VA_ARGS__)
#define memory_slice(...) __CPROVER_object_upto(__VA_ARGS__)
#define same_object(...) __CPROVER_same_object(__VA_ARGS__)
/*
* Pointer-related predicates
* https://diffblue.github.io/cbmc/contracts-memory-predicates.html
*/
#define memory_no_alias(...) __CPROVER_is_fresh(__VA_ARGS__)
#define readable(...) __CPROVER_r_ok(__VA_ARGS__)
#define writeable(...) __CPROVER_w_ok(__VA_ARGS__)
/*
* History variables
* https://diffblue.github.io/cbmc/contracts-history-variables.html
*/
#define old(...) __CPROVER_old(__VA_ARGS__)
#define loop_entry(...) __CPROVER_loop_entry(__VA_ARGS__)
/*
* Quantifiers
* Note that the range on qvar is _exclusive_ between qvar_lb .. qvar_ub
* https://diffblue.github.io/cbmc/contracts-quantifiers.html
*/
/*
* Prevent clang-format from corrupting CBMC's special ==> operator
*/
/* clang-format off */
#define forall(qvar, qvar_lb, qvar_ub, predicate) \
__CPROVER_forall \
{ \
unsigned qvar; \
((qvar_lb) <= (qvar) && (qvar) < (qvar_ub)) ==> (predicate) \
}
#define EXISTS(qvar, qvar_lb, qvar_ub, predicate) \
__CPROVER_exists \
{ \
unsigned qvar; \
((qvar_lb) <= (qvar) && (qvar) < (qvar_ub)) && (predicate) \
}
/* clang-format on */
/***************************************************
* Convenience macros for common contract patterns
***************************************************/
/*
* Boolean-value predidate that asserts that "all values of array_var are in
* range value_lb (inclusive) .. value_ub (exclusive)"
* Example:
* array_bound(a->coeffs, 0, MLKEM_N, 0, MLKEM_Q)
* expands to
* __CPROVER_forall { int k; (0 <= k && k <= MLKEM_N-1) ==> (
* 0 <= a->coeffs[k]) && a->coeffs[k] < MLKEM_Q)) }
*/
/*
* Prevent clang-format from corrupting CBMC's special ==> operator
*/
/* clang-format off */
#define CBMC_CONCAT_(left, right) left##right
#define CBMC_CONCAT(left, right) CBMC_CONCAT_(left, right)
#define array_bound_core(qvar, qvar_lb, qvar_ub, array_var, \
value_lb, value_ub) \
__CPROVER_forall \
{ \
unsigned qvar; \
((qvar_lb) <= (qvar) && (qvar) < (qvar_ub)) ==> \
(((int)(value_lb) <= ((array_var)[(qvar)])) && \
(((array_var)[(qvar)]) < (int)(value_ub))) \
}
#define array_bound(array_var, qvar_lb, qvar_ub, value_lb, value_ub) \
array_bound_core(CBMC_CONCAT(_cbmc_idx, __LINE__), (qvar_lb), \
(qvar_ub), (array_var), (value_lb), (value_ub))
/* clang-format on */
/* Wrapper around array_bound operating on absolute values.
*
* Note that since the absolute bound is inclusive, but the lower
* bound in array_bound is inclusive, we have to raise it by 1.
*/
#define array_abs_bound(arr, lb, ub, k) \
array_bound((arr), (lb), (ub), -((int)(k)) + 1, (k))
#endif
#endif /* MLK_CBMC_H */