You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A topic that often accompanies the more general trust question is Lean's robustness against adversarial inputs.
19
-
20
-
A correct type checker will restrict the input it receives to the rules of Lean's type system under whatever axioms the operator allows. If the operator restricts the permitted axioms to the three "official" ones (`propext`, `Quot.sound`, `Classical.choice`), an input file should not be able to offer a proof of the prelude's `False` which is accepted by the type checker under any circumstances.
21
-
22
-
However, a minimal type checker will not actively protect against inputs which provide Lean declarations that are logically sound, but are designed to fool a human operator. For example, redefining deep dependencies an adversary knows will not be examined by a referee, or introducing unicode lookalikes to produce a pretty printer output that conceals modification of key definitions.
23
-
24
-
The idea that "a user might think a theorem has been formally proved, while in fact he or she
25
-
is misled about what it is that the system has actually done" is addressed by the idea of Pollack consistency and is explored in this publication[^pollack] by Freek Wiedijk.
26
-
27
-
Note that there is nothing in principle preventing developers from writing software or extending a type checker to provide protection against such attacks, it's just not captured by the minimal functionality required by the kernel. However, the extent to which Lean's users have embraced its powerful custom syntax and macro systems may pose some challenges for those interested in improving the story here. Readers should consider this somewhat of an [open issue for future work](../future_work.md#improving-pollack-consistency)
A big part of Lean's value proposition is the ability to construct mathematical proofs, including proofs about program correctness. A common question from users is how much trust, and in what exactly, is involved in trusting Lean.
20
-
21
-
An answer to this question has two parts: what users need to trust in order to trust proofs in Lean, and what users need to trust in order to trust executable programs obtained by compiling a Lean program.
22
-
23
-
Concretely, the distinction is that proofs (which includes statements about programs) and uncompiled programs can be expressed directly in Lean's kernel language and checked by an implementation of the kernel. They do not need to be compiled to an executable, therefore the trust is limited to whatever implementation of the kernel they're being checked with, and the Lean compiler does not become part of the trusted code base.
24
-
25
-
Trusting the correctness of compiled Lean programs requires trust in Lean's compiler, which is separate from the kernel and is not part of Lean's core logic. There is a distinction between trusting _statements about programs_ in Lean, and trusting _programs produced by the Lean compiler_. Statements about Lean programs are proofs, and fall into the category that only requires trust in the kernel. Trusting that proofs about a program _extend to the behavior of a compiled program_ brings the compiler into the trusted code base.
26
-
27
-
**NOTE**: Tactics and other metaprograms, even tactics that are compiled, do *not* need to be trusted _at all_; they are untrusted code which is used to produce kernel terms for use by something else. A proposition `P` can be proved in Lean using an arbitrarily complex compiled metaprogram without expanding the trusted code base beyond the kernel, because the metaprogram is required to produce a proof expressed in Lean's kernel language.
28
-
29
-
+ These statements hold for proofs that are [exported](../export_format.md). To satisfy more ~~pedantic~~ vigilant readers, this does necessarily entail some degree of trust in, for example, the operating system on the computer used to run the exporter and verifier, the hardware, etc.
30
-
31
-
+ For proofs that are not exported, users are additionally trusting the elements of Lean outside the kernel (the elaborator, parser, etc.).
32
-
33
-
## A more itemized list
34
-
35
-
A more itemized description of the trust involved in Lean 4 comes from a post by Mario Carneiro on the Lean Zulip.
36
-
37
-
> In general:
38
-
>
39
-
> 1. You trust that the lean logic is sound (author's note: this would include any kernel extensions, like those for Nat and String)
40
-
>
41
-
> 2. If you didn't prove the program correct, you trust that the elaborator has converted your input into the lean expression denoting the program you expect.
42
-
>
43
-
> 3. If you did prove the program correct, you trust that the proofs about the program have been checked (use external checkers to eliminate this)
44
-
>
45
-
> 4. You trust that the hardware / firmware / OS software running all of these things didn't break or lie to you
46
-
>
47
-
> 5. (When running the program) You trust that the hardware / firmware / OS software faithfully executes the program according to spec and there are no debuggers or magnets on the hard drive or cosmic rays messing with your output
48
-
>
49
-
> For compiled executables:
50
-
>
51
-
> 6. You trust that any compiler overrides (extern / implemented_by) do not violate the lean logic (i.e. the model matches the implementation)
52
-
>
53
-
> 7. You trust the lean compiler (which lowered the lean code to C) to preserve the semantics of the program
54
-
>
55
-
> 8. You trust clang / LLVM to convert the C program into an executable with the same semantics
56
-
57
-
The first set of points applies to both proofs and compiled executables, while the second set applies specifically to compiled executable programs.
58
-
59
-
## Trust for external checkers
60
-
61
-
1. You're still trusting Lean's logic is sound.
62
-
63
-
2. You're trusting that the developers of the external checker properly implemented the program.
64
-
65
-
3. You're trusting the implementing language's compiler or interpreter. If you run multiple external checkers, you can think of them as circles in a venn diagram; you're trusting that the part where the circles intersect is free of soundness issues.
66
-
67
-
4. For the Nat and String kernel extensions, you're probably trusting a bignum library and the UTF-8 string type of the implementing language.
68
-
69
-
The advantages of using external checkers are:
70
-
71
-
+ Users can check their results with something that is completely disjoint from the Lean ecosystem, and is not dependent on any parts of Lean's code base.
72
-
73
-
+ External checkers can be written to take advantage of mature compilers or interpreters.
74
-
75
-
+ For kernel extensions, users can cross-check the results of multiple bignum/string implementations.
76
-
77
-
+ Using the export feature is the only way to get out of trusting the parts of Lean outside the kernel, so there's a benefit to doing this even if the export file is checked by something like [lean4lean](https://github.com/digama0/lean4lean/tree/master). Users worried about fallout from misuse of Lean's metaprogramming features are therefore encouraged to use the export feature.
0 commit comments