Skip to content

Commit fc2599e

Browse files
authored
Merge pull request #1422 from cryspen/barrett-example-tutorial
Barrett example tutorial
2 parents e8b4386 + 8151953 commit fc2599e

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

docs/manual/tutorial/properties.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const BARRETT_SHIFT: i64 = 26;
4848
const BARRETT_R: i64 = 0x4000000; // 2^26
4949
const BARRETT_MULTIPLIER: i64 = 20159; // ⌊(BARRETT_R / FIELD_MODULUS) + 1/2⌋
5050
51+
#[hax_lib::fstar::options("--z3rlimit 100")]
5152
#[hax_lib::requires((i64::from(value) >= -BARRETT_R && i64::from(value) <= BARRETT_R))]
5253
#[hax_lib::ensures(|result| result > -FIELD_MODULUS && result < FIELD_MODULUS
5354
&& result % FIELD_MODULUS == value % FIELD_MODULUS)]
@@ -60,9 +61,6 @@ fn barrett_reduce(value: i32) -> i32 {
6061
6162
let sub = quotient * FIELD_MODULUS;
6263
63-
// Here a lemma to prove that `(quotient * 3329) % 3329 = 0`
64-
// may have to be called in F*.
65-
6664
value - sub
6765
}
6866
```
@@ -71,13 +69,26 @@ fn barrett_reduce(value: i32) -> i32 {
7169
effect, but in F*, that establishes that `(quotient * 3329) % 3329` is
7270
zero. -->
7371

74-
Before returning, a lemma may have to be called in F* to prove the correctness
75-
of the reduction.
76-
The lemma is `Math.Lemmas.cancel_mul_mod (v quotient) 3329;`, which establishes
77-
that `(quotient * 3329) % 3329` is zero.
78-
With the help of that one lemma, F\* is able to prove the
79-
reduction computes the expected result.
80-
(We may expose lemmas like this to call from Rust directly in future.)
72+
The proof for the code above uses the Z3 SMT solver to prive the
73+
post-condition. Since the SMT solver needs to reason about non-linear
74+
arithmetic (multiplication, modulus, division) it needs more
75+
resources, hence we bump up the `rlimit` to 100 in an annotation above
76+
the function. With this annotation F* and Z3 are able to automatically
77+
verify this function. However, it is worth noting that the heuristic
78+
strategies used by Z3 for non-linear arithmetic may sometimes fail to
79+
complete in the given `rlimit` depending on the solver version or random
80+
number generator, so we often give Z3 a generous resource limit.
81+
82+
Conversely, instead of relying on the SMT solver, we can also
83+
elaborate the proof of this function by hand to make it more
84+
predictable. For example, before the final line of the function,
85+
we could call a mathematical lemma may have to help F* prove
86+
the correctness of the reduction. The lemma call would be:
87+
```
88+
fstar!("Math.Lemmas.cancel_mul_mod (v quotient) 3329");
89+
```
90+
This lemma establishes that `(quotient * 3329) % 3329` is zero. We often use lemmas like
91+
these to limit our dependence on Z3.
8192

8293
This Barrett reduction examples is taken from
8394
[libcrux](https://github.com/cryspen/libcrux/tree/main)'s proof of

examples/Cargo.lock

Lines changed: 27 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/barrett/proofs/fstar/extraction/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ all:
5353
rm -f .depend && $(MAKE) .depend
5454
$(MAKE) verify
5555

56-
HAX_CLI = "cargo hax into fstar --z3rlimit 1000"
56+
HAX_CLI = "cargo hax into fstar --z3rlimit 100"
5757

5858
# If $HACL_HOME doesn't exist, clone it
5959
${HACL_HOME}:

examples/barrett/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) const FIELD_MODULUS: i32 = 3329;
2323
/// `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1)
2424
///
2525
/// In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`.
26+
#[hax_lib::fstar::options("--z3rlimit 100")]
2627
#[hax::requires((i64::from(value) >= -BARRETT_R && i64::from(value) <= BARRETT_R))]
2728
#[hax::ensures(|result| result > -FIELD_MODULUS && result < FIELD_MODULUS &&
2829
result % FIELD_MODULUS == value % FIELD_MODULUS)]

0 commit comments

Comments
 (0)