proof-frog 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- proof_frog-0.3.0/LICENSE +21 -0
- proof_frog-0.3.0/PKG-INFO +202 -0
- proof_frog-0.3.0/README.md +171 -0
- proof_frog-0.3.0/proof_frog/.DS_Store +0 -0
- proof_frog-0.3.0/proof_frog/__init__.py +1 -0
- proof_frog-0.3.0/proof_frog/__main__.py +3 -0
- proof_frog-0.3.0/proof_frog/antlr/Game.g4 +7 -0
- proof_frog-0.3.0/proof_frog/antlr/Primitive.g4 +7 -0
- proof_frog-0.3.0/proof_frog/antlr/Proof.g4 +46 -0
- proof_frog-0.3.0/proof_frog/antlr/Scheme.g4 +13 -0
- proof_frog-0.3.0/proof_frog/antlr/Shared.g4 +174 -0
- proof_frog-0.3.0/proof_frog/dependencies.py +264 -0
- proof_frog-0.3.0/proof_frog/describe.py +114 -0
- proof_frog-0.3.0/proof_frog/frog_ast.py +845 -0
- proof_frog-0.3.0/proof_frog/frog_parser.py +882 -0
- proof_frog-0.3.0/proof_frog/mcp_server.py +447 -0
- proof_frog-0.3.0/proof_frog/parsing/Game.interp +153 -0
- proof_frog-0.3.0/proof_frog/parsing/Game.tokens +112 -0
- proof_frog-0.3.0/proof_frog/parsing/GameLexer.interp +194 -0
- proof_frog-0.3.0/proof_frog/parsing/GameLexer.py +257 -0
- proof_frog-0.3.0/proof_frog/parsing/GameLexer.tokens +112 -0
- proof_frog-0.3.0/proof_frog/parsing/GameParser.py +3990 -0
- proof_frog-0.3.0/proof_frog/parsing/GameVisitor.py +368 -0
- proof_frog-0.3.0/proof_frog/parsing/Primitive.interp +153 -0
- proof_frog-0.3.0/proof_frog/parsing/Primitive.tokens +112 -0
- proof_frog-0.3.0/proof_frog/parsing/PrimitiveLexer.interp +194 -0
- proof_frog-0.3.0/proof_frog/parsing/PrimitiveLexer.py +257 -0
- proof_frog-0.3.0/proof_frog/parsing/PrimitiveLexer.tokens +112 -0
- proof_frog-0.3.0/proof_frog/parsing/PrimitiveParser.py +4032 -0
- proof_frog-0.3.0/proof_frog/parsing/PrimitiveVisitor.py +368 -0
- proof_frog-0.3.0/proof_frog/parsing/Proof.interp +189 -0
- proof_frog-0.3.0/proof_frog/parsing/Proof.tokens +136 -0
- proof_frog-0.3.0/proof_frog/parsing/ProofLexer.interp +230 -0
- proof_frog-0.3.0/proof_frog/parsing/ProofLexer.py +314 -0
- proof_frog-0.3.0/proof_frog/parsing/ProofLexer.tokens +136 -0
- proof_frog-0.3.0/proof_frog/parsing/ProofParser.py +5029 -0
- proof_frog-0.3.0/proof_frog/parsing/ProofVisitor.py +433 -0
- proof_frog-0.3.0/proof_frog/parsing/Scheme.interp +160 -0
- proof_frog-0.3.0/proof_frog/parsing/Scheme.tokens +118 -0
- proof_frog-0.3.0/proof_frog/parsing/SchemeLexer.interp +203 -0
- proof_frog-0.3.0/proof_frog/parsing/SchemeLexer.py +270 -0
- proof_frog-0.3.0/proof_frog/parsing/SchemeLexer.tokens +118 -0
- proof_frog-0.3.0/proof_frog/parsing/SchemeParser.py +4144 -0
- proof_frog-0.3.0/proof_frog/parsing/SchemeVisitor.py +373 -0
- proof_frog-0.3.0/proof_frog/parsing/__init__.py +0 -0
- proof_frog-0.3.0/proof_frog/proof_engine.py +939 -0
- proof_frog-0.3.0/proof_frog/proof_frog.py +143 -0
- proof_frog-0.3.0/proof_frog/semantic_analysis.py +1300 -0
- proof_frog-0.3.0/proof_frog/visitors.py +1760 -0
- proof_frog-0.3.0/proof_frog/web/app.js +54 -0
- proof_frog-0.3.0/proof_frog/web/cm-mode.js +51 -0
- proof_frog-0.3.0/proof_frog/web/editor.js +269 -0
- proof_frog-0.3.0/proof_frog/web/favicon.ico +0 -0
- proof_frog-0.3.0/proof_frog/web/file-tree.js +85 -0
- proof_frog-0.3.0/proof_frog/web/game-hops.js +121 -0
- proof_frog-0.3.0/proof_frog/web/index.html +101 -0
- proof_frog-0.3.0/proof_frog/web/inline-game.js +270 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-128.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-16.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-180.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-32.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-48.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog-64.png +0 -0
- proof_frog-0.3.0/proof_frog/web/prooffrog.png +0 -0
- proof_frog-0.3.0/proof_frog/web/resize.js +107 -0
- proof_frog-0.3.0/proof_frog/web/state.js +61 -0
- proof_frog-0.3.0/proof_frog/web/style.css +289 -0
- proof_frog-0.3.0/proof_frog/web/wizard.js +91 -0
- proof_frog-0.3.0/proof_frog/web_server.py +475 -0
- proof_frog-0.3.0/pyproject.toml +95 -0
proof_frog-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ross Evans
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proof_frog
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: A tool for checking transitions in cryptographic game-hopping proofs
|
|
5
|
+
Keywords: cryptography,latex,game-hopping,proofs
|
|
6
|
+
Author-email: Ross Evans <rpevans@uwaterloo.ca>, Douglas Stebila <dstebila@uwaterloo.ca>
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Security :: Cryptography
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: antlr4-python3-runtime >= 4.13
|
|
20
|
+
Requires-Dist: colorama >= 0.4
|
|
21
|
+
Requires-Dist: z3-solver >= 4.12
|
|
22
|
+
Requires-Dist: sympy >= 1.12
|
|
23
|
+
Requires-Dist: flask >= 3.0
|
|
24
|
+
Requires-Dist: click >= 8.0
|
|
25
|
+
Requires-Dist: mcp[cli] >= 1.0 ; extra == "mcp"
|
|
26
|
+
Project-URL: Documentation, https://prooffrog.github.io
|
|
27
|
+
Project-URL: Release Notes, https://github.com/ProofFrog/ProofFrog/blob/main/RELEASE.md
|
|
28
|
+
Project-URL: Source, https://github.com/ProofFrog/ProofFrog
|
|
29
|
+
Provides-Extra: mcp
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="https://github.com/ProofFrog/ProofFrog/blob/main/proof_frog/web/prooffrog.png?raw=true" alt="ProofFrog logo" width="120"/>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
# ProofFrog
|
|
36
|
+
|
|
37
|
+
**A tool for checking transitions in cryptographic game-hopping proofs.**
|
|
38
|
+
|
|
39
|
+
ProofFrog checks the validity of transitions in game-hopping proofs — the standard technique in provable security for showing that a cryptographic scheme satisfies a security property. Proofs are written in FrogLang, a domain-specific language for defining primitives, schemes, security games, and proofs. ProofFrog is designed to handle introductory-level proofs, trading expressivity and power for ease of use. The engine checks each hop by manipulating abstract syntax trees into a canonical form, with some help from other tools like Z3 and SymPy. ProofFrog's engine does not have any formal guarantees: the soundness of its transformations has not been verified.
|
|
40
|
+
|
|
41
|
+
ProofFrog can be used via a **command-line interface**, a **browser-based editor**, or an **MCP server** for integration with AI coding assistants. More info at [prooffrog.github.io](https://prooffrog.github.io/).
|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
Requires **Python 3.11+**.
|
|
48
|
+
|
|
49
|
+
### From PyPI
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
python3 -m venv .venv
|
|
53
|
+
source .venv/bin/activate
|
|
54
|
+
pip install proof_frog
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### From source
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
git clone https://github.com/ProofFrog/ProofFrog
|
|
61
|
+
cd ProofFrog
|
|
62
|
+
git submodule update --init
|
|
63
|
+
python3 -m venv .venv
|
|
64
|
+
source .venv/bin/activate
|
|
65
|
+
pip install -e .
|
|
66
|
+
pip install -r requirements-dev.txt
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Web Interface
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
proof_frog web [directory]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Starts a local web server (default port 5173) and opens the editor in your browser. The `[directory]` argument specifies the working directory for proof files; it defaults to the current directory.
|
|
76
|
+
|
|
77
|
+
The web interface lets you edit ProofFrog files (with syntax highlighting), validate proofs from the web editor, and explore the game state at each hop.
|
|
78
|
+
|
|
79
|
+
## Command-Line Interface
|
|
80
|
+
|
|
81
|
+
| Command | Description |
|
|
82
|
+
|---------|-------------|
|
|
83
|
+
| `proof_frog parse <file>` | Parse a file and print its AST representation |
|
|
84
|
+
| `proof_frog check <file>` | Type-check a file for well-formedness |
|
|
85
|
+
| `proof_frog prove <file>` | Verify a game-hopping proof (`-v` for verbose output) |
|
|
86
|
+
| `proof_frog web [dir]` | Launch the browser-based editor |
|
|
87
|
+
|
|
88
|
+
When installed from source, use `python3 -m proof_frog` instead of `proof_frog`.
|
|
89
|
+
|
|
90
|
+
## Writing a Proof in ProofFrog
|
|
91
|
+
|
|
92
|
+
Take a look at the [guide](https://github.com/ProofFrog/ProofFrog/blob/main/docs/guide.md) for writing a proof in ProofFrog.
|
|
93
|
+
|
|
94
|
+
ProofFrog uses four file types to express the components of a cryptographic proof.
|
|
95
|
+
|
|
96
|
+
### Primitives (`.primitive`)
|
|
97
|
+
|
|
98
|
+
A **primitive** defines the interface for a cryptographic operation — its parameters, types, and method signatures. Here's an example of the interface for a pseudorandom generator:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Primitive PRG(Int lambda, Int stretch) {
|
|
102
|
+
Int lambda = lambda;
|
|
103
|
+
Int stretch = stretch;
|
|
104
|
+
|
|
105
|
+
BitString<lambda + stretch> evaluate(BitString<lambda> x);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Schemes (`.scheme`)
|
|
110
|
+
|
|
111
|
+
A **scheme** implements a primitive. Schemes can be built generically from other primitives. Here's an example of the one-time pad symmetric encryption scheme:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
Scheme OTP(Int lambda) extends SymEnc {
|
|
115
|
+
Set Key = BitString<lambda>;
|
|
116
|
+
Set Message = BitString<lambda>;
|
|
117
|
+
Set Ciphertext = BitString<lambda>;
|
|
118
|
+
|
|
119
|
+
Key KeyGen() {
|
|
120
|
+
Key k <- Key;
|
|
121
|
+
return k;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
Ciphertext Enc(Key k, Message m) {
|
|
125
|
+
return k + m;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Message Dec(Key k, Ciphertext c) {
|
|
129
|
+
return k + c;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Games (`.game`)
|
|
135
|
+
|
|
136
|
+
A **security property** is defined as a pair of games (Left/Right). An adversary's inability to distinguish between the two games constitutes security. Here's an example of the security game for a PRG:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Game Real(PRG G) {
|
|
140
|
+
BitString<G.lambda + G.stretch> Query() {
|
|
141
|
+
BitString<G.lambda> s <- BitString<G.lambda>;
|
|
142
|
+
return G.evaluate(s);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Game Random(PRG G) {
|
|
147
|
+
BitString<G.lambda + G.stretch> Query() {
|
|
148
|
+
BitString<G.lambda + G.stretch> r <- BitString<G.lambda + G.stretch>;
|
|
149
|
+
return r;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export as Security;
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Proofs (`.proof`)
|
|
157
|
+
|
|
158
|
+
A **proof script** declares assumptions, states a theorem, and lists a sequence of games. Each adjacent pair must be justified as either code-equivalent (verified automatically) or a reduction to an assumed security property. The following snippet shows the basic parts of a proof:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
proof:
|
|
162
|
+
|
|
163
|
+
let:
|
|
164
|
+
SymEnc proofE = SymEnc(ProofMessageSpace, ProofCiphertextSpace, ProofKeySpace);
|
|
165
|
+
|
|
166
|
+
assume:
|
|
167
|
+
OneTimeUniformCiphertexts(proofE);
|
|
168
|
+
|
|
169
|
+
theorem:
|
|
170
|
+
OneTimeSecrecy(proofE);
|
|
171
|
+
|
|
172
|
+
games:
|
|
173
|
+
OneTimeSecrecy(proofE).Left against OneTimeSecrecy(proofE).Adversary;
|
|
174
|
+
OneTimeUniformCiphertexts(proofE).Real compose R1(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
175
|
+
OneTimeUniformCiphertexts(proofE).Random compose R1(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
176
|
+
OneTimeUniformCiphertexts(proofE).Random compose R2(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
177
|
+
OneTimeUniformCiphertexts(proofE).Real compose R2(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
178
|
+
OneTimeSecrecy(proofE).Right against OneTimeSecrecy(proofE).Adversary;
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Vibe-Coding a Proof
|
|
182
|
+
|
|
183
|
+
ProofFrog also provides an MCP server for integration with AI coding assistants like Claude Code. See the ProofFrog website for an [example of vibe-coding a ProofFrog proof with Claude Code](https://prooffrog.github.io/hacs-2026/vibe/).
|
|
184
|
+
|
|
185
|
+
## Examples
|
|
186
|
+
|
|
187
|
+
The [`examples/`](https://github.com/ProofFrog/examples) repository contains primitives, schemes, games, and proofs largely adapted from [*The Joy of Cryptography*](https://joyofcryptography.com/) by Mike Rosulek. See also the [examples and tutorials on the ProofFrog website](https://prooffrog.github.io/).
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
ProofFrog is released under the [MIT License](https://github.com/ProofFrog/ProofFrog/blob/main/LICENSE).
|
|
192
|
+
|
|
193
|
+
## Acknowledgements
|
|
194
|
+
|
|
195
|
+
ProofFrog was created by Ross Evans and Douglas Stebila, building on the pygamehop tool created by Douglas Stebila and Matthew McKague. For more information about ProofFrog's design, see [Ross Evans' master's thesis](https://uwspace.uwaterloo.ca/bitstream/handle/10012/20441/Evans_Ross.pdf) and [eprint 2025/418](https://eprint.iacr.org/2025/418).
|
|
196
|
+
|
|
197
|
+
<img src="https://github.com/ProofFrog/ProofFrog/blob/main/media/NSERC.jpg?raw=true" alt="NSERC logo" width="750"/>
|
|
198
|
+
|
|
199
|
+
We acknowledge the support of the Natural Sciences and Engineering Research Council of Canada (NSERC).
|
|
200
|
+
|
|
201
|
+
Includes icons from the [vscode-codicons](https://github.com/microsoft/vscode-codicons) project.
|
|
202
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://github.com/ProofFrog/ProofFrog/blob/main/proof_frog/web/prooffrog.png?raw=true" alt="ProofFrog logo" width="120"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# ProofFrog
|
|
6
|
+
|
|
7
|
+
**A tool for checking transitions in cryptographic game-hopping proofs.**
|
|
8
|
+
|
|
9
|
+
ProofFrog checks the validity of transitions in game-hopping proofs — the standard technique in provable security for showing that a cryptographic scheme satisfies a security property. Proofs are written in FrogLang, a domain-specific language for defining primitives, schemes, security games, and proofs. ProofFrog is designed to handle introductory-level proofs, trading expressivity and power for ease of use. The engine checks each hop by manipulating abstract syntax trees into a canonical form, with some help from other tools like Z3 and SymPy. ProofFrog's engine does not have any formal guarantees: the soundness of its transformations has not been verified.
|
|
10
|
+
|
|
11
|
+
ProofFrog can be used via a **command-line interface**, a **browser-based editor**, or an **MCP server** for integration with AI coding assistants. More info at [prooffrog.github.io](https://prooffrog.github.io/).
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Requires **Python 3.11+**.
|
|
18
|
+
|
|
19
|
+
### From PyPI
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
python3 -m venv .venv
|
|
23
|
+
source .venv/bin/activate
|
|
24
|
+
pip install proof_frog
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### From source
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
git clone https://github.com/ProofFrog/ProofFrog
|
|
31
|
+
cd ProofFrog
|
|
32
|
+
git submodule update --init
|
|
33
|
+
python3 -m venv .venv
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
pip install -e .
|
|
36
|
+
pip install -r requirements-dev.txt
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Web Interface
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
proof_frog web [directory]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Starts a local web server (default port 5173) and opens the editor in your browser. The `[directory]` argument specifies the working directory for proof files; it defaults to the current directory.
|
|
46
|
+
|
|
47
|
+
The web interface lets you edit ProofFrog files (with syntax highlighting), validate proofs from the web editor, and explore the game state at each hop.
|
|
48
|
+
|
|
49
|
+
## Command-Line Interface
|
|
50
|
+
|
|
51
|
+
| Command | Description |
|
|
52
|
+
|---------|-------------|
|
|
53
|
+
| `proof_frog parse <file>` | Parse a file and print its AST representation |
|
|
54
|
+
| `proof_frog check <file>` | Type-check a file for well-formedness |
|
|
55
|
+
| `proof_frog prove <file>` | Verify a game-hopping proof (`-v` for verbose output) |
|
|
56
|
+
| `proof_frog web [dir]` | Launch the browser-based editor |
|
|
57
|
+
|
|
58
|
+
When installed from source, use `python3 -m proof_frog` instead of `proof_frog`.
|
|
59
|
+
|
|
60
|
+
## Writing a Proof in ProofFrog
|
|
61
|
+
|
|
62
|
+
Take a look at the [guide](https://github.com/ProofFrog/ProofFrog/blob/main/docs/guide.md) for writing a proof in ProofFrog.
|
|
63
|
+
|
|
64
|
+
ProofFrog uses four file types to express the components of a cryptographic proof.
|
|
65
|
+
|
|
66
|
+
### Primitives (`.primitive`)
|
|
67
|
+
|
|
68
|
+
A **primitive** defines the interface for a cryptographic operation — its parameters, types, and method signatures. Here's an example of the interface for a pseudorandom generator:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Primitive PRG(Int lambda, Int stretch) {
|
|
72
|
+
Int lambda = lambda;
|
|
73
|
+
Int stretch = stretch;
|
|
74
|
+
|
|
75
|
+
BitString<lambda + stretch> evaluate(BitString<lambda> x);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Schemes (`.scheme`)
|
|
80
|
+
|
|
81
|
+
A **scheme** implements a primitive. Schemes can be built generically from other primitives. Here's an example of the one-time pad symmetric encryption scheme:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Scheme OTP(Int lambda) extends SymEnc {
|
|
85
|
+
Set Key = BitString<lambda>;
|
|
86
|
+
Set Message = BitString<lambda>;
|
|
87
|
+
Set Ciphertext = BitString<lambda>;
|
|
88
|
+
|
|
89
|
+
Key KeyGen() {
|
|
90
|
+
Key k <- Key;
|
|
91
|
+
return k;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Ciphertext Enc(Key k, Message m) {
|
|
95
|
+
return k + m;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Message Dec(Key k, Ciphertext c) {
|
|
99
|
+
return k + c;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Games (`.game`)
|
|
105
|
+
|
|
106
|
+
A **security property** is defined as a pair of games (Left/Right). An adversary's inability to distinguish between the two games constitutes security. Here's an example of the security game for a PRG:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Game Real(PRG G) {
|
|
110
|
+
BitString<G.lambda + G.stretch> Query() {
|
|
111
|
+
BitString<G.lambda> s <- BitString<G.lambda>;
|
|
112
|
+
return G.evaluate(s);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
Game Random(PRG G) {
|
|
117
|
+
BitString<G.lambda + G.stretch> Query() {
|
|
118
|
+
BitString<G.lambda + G.stretch> r <- BitString<G.lambda + G.stretch>;
|
|
119
|
+
return r;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export as Security;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Proofs (`.proof`)
|
|
127
|
+
|
|
128
|
+
A **proof script** declares assumptions, states a theorem, and lists a sequence of games. Each adjacent pair must be justified as either code-equivalent (verified automatically) or a reduction to an assumed security property. The following snippet shows the basic parts of a proof:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
proof:
|
|
132
|
+
|
|
133
|
+
let:
|
|
134
|
+
SymEnc proofE = SymEnc(ProofMessageSpace, ProofCiphertextSpace, ProofKeySpace);
|
|
135
|
+
|
|
136
|
+
assume:
|
|
137
|
+
OneTimeUniformCiphertexts(proofE);
|
|
138
|
+
|
|
139
|
+
theorem:
|
|
140
|
+
OneTimeSecrecy(proofE);
|
|
141
|
+
|
|
142
|
+
games:
|
|
143
|
+
OneTimeSecrecy(proofE).Left against OneTimeSecrecy(proofE).Adversary;
|
|
144
|
+
OneTimeUniformCiphertexts(proofE).Real compose R1(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
145
|
+
OneTimeUniformCiphertexts(proofE).Random compose R1(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
146
|
+
OneTimeUniformCiphertexts(proofE).Random compose R2(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
147
|
+
OneTimeUniformCiphertexts(proofE).Real compose R2(proofE) against OneTimeSecrecy(proofE).Adversary;
|
|
148
|
+
OneTimeSecrecy(proofE).Right against OneTimeSecrecy(proofE).Adversary;
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Vibe-Coding a Proof
|
|
152
|
+
|
|
153
|
+
ProofFrog also provides an MCP server for integration with AI coding assistants like Claude Code. See the ProofFrog website for an [example of vibe-coding a ProofFrog proof with Claude Code](https://prooffrog.github.io/hacs-2026/vibe/).
|
|
154
|
+
|
|
155
|
+
## Examples
|
|
156
|
+
|
|
157
|
+
The [`examples/`](https://github.com/ProofFrog/examples) repository contains primitives, schemes, games, and proofs largely adapted from [*The Joy of Cryptography*](https://joyofcryptography.com/) by Mike Rosulek. See also the [examples and tutorials on the ProofFrog website](https://prooffrog.github.io/).
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
ProofFrog is released under the [MIT License](https://github.com/ProofFrog/ProofFrog/blob/main/LICENSE).
|
|
162
|
+
|
|
163
|
+
## Acknowledgements
|
|
164
|
+
|
|
165
|
+
ProofFrog was created by Ross Evans and Douglas Stebila, building on the pygamehop tool created by Douglas Stebila and Matthew McKague. For more information about ProofFrog's design, see [Ross Evans' master's thesis](https://uwspace.uwaterloo.ca/bitstream/handle/10012/20441/Evans_Ross.pdf) and [eprint 2025/418](https://eprint.iacr.org/2025/418).
|
|
166
|
+
|
|
167
|
+
<img src="https://github.com/ProofFrog/ProofFrog/blob/main/media/NSERC.jpg?raw=true" alt="NSERC logo" width="750"/>
|
|
168
|
+
|
|
169
|
+
We acknowledge the support of the Natural Sciences and Engineering Research Council of Canada (NSERC).
|
|
170
|
+
|
|
171
|
+
Includes icons from the [vscode-codicons](https://github.com/microsoft/vscode-codicons) project.
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .proof_frog import main
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
grammar Proof;
|
|
2
|
+
|
|
3
|
+
import Shared;
|
|
4
|
+
|
|
5
|
+
program: moduleImport* proofHelpers proof EOF;
|
|
6
|
+
|
|
7
|
+
proofHelpers: (reduction | game)*;
|
|
8
|
+
|
|
9
|
+
reduction: REDUCTION ID L_PAREN paramList? R_PAREN COMPOSE parameterizedGame AGAINST gameAdversary L_CURLY gameBody R_CURLY;
|
|
10
|
+
|
|
11
|
+
proof: PROOF COLON (LET COLON lets)? (ASSUME COLON assumptions)? THEOREM COLON theorem GAMES COLON gameList;
|
|
12
|
+
|
|
13
|
+
lets: (field SEMI)*;
|
|
14
|
+
|
|
15
|
+
assumptions: (parameterizedGame SEMI)* (CALLS (LEQ|L_ANGLE) expression SEMI)?;
|
|
16
|
+
|
|
17
|
+
theorem: parameterizedGame SEMI;
|
|
18
|
+
|
|
19
|
+
gameList: gameStep SEMI (gameStep SEMI|induction|stepAssumption)*;
|
|
20
|
+
|
|
21
|
+
gameStep: concreteGame COMPOSE parameterizedGame AGAINST gameAdversary # reductionStep
|
|
22
|
+
| (concreteGame|parameterizedGame) AGAINST gameAdversary # regularStep
|
|
23
|
+
;
|
|
24
|
+
|
|
25
|
+
induction: INDUCTION L_PAREN ID FROM integerExpression TO integerExpression R_PAREN L_CURLY gameList R_CURLY;
|
|
26
|
+
|
|
27
|
+
stepAssumption: ASSUME expression SEMI;
|
|
28
|
+
|
|
29
|
+
gameField: (concreteGame | parameterizedGame) PERIOD ID;
|
|
30
|
+
|
|
31
|
+
concreteGame: parameterizedGame PERIOD ID;
|
|
32
|
+
gameAdversary: parameterizedGame PERIOD ADVERSARY;
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
REDUCTION: 'Reduction';
|
|
36
|
+
AGAINST: 'against';
|
|
37
|
+
ADVERSARY: 'Adversary';
|
|
38
|
+
COMPOSE: 'compose';
|
|
39
|
+
PROOF: 'proof';
|
|
40
|
+
ASSUME: 'assume';
|
|
41
|
+
THEOREM: 'theorem';
|
|
42
|
+
GAMES: 'games';
|
|
43
|
+
LET: 'let';
|
|
44
|
+
CALLS: 'calls';
|
|
45
|
+
INDUCTION: 'induction';
|
|
46
|
+
FROM: 'from';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
grammar Scheme;
|
|
2
|
+
|
|
3
|
+
import Shared;
|
|
4
|
+
|
|
5
|
+
program: moduleImport* scheme EOF;
|
|
6
|
+
|
|
7
|
+
scheme: SCHEME ID L_PAREN paramList? R_PAREN EXTENDS ID L_CURLY schemeBody R_CURLY;
|
|
8
|
+
|
|
9
|
+
schemeBody: (REQUIRES expression SEMI)* (field SEMI | method)+;
|
|
10
|
+
|
|
11
|
+
REQUIRES: 'requires';
|
|
12
|
+
SCHEME: 'Scheme';
|
|
13
|
+
EXTENDS: 'extends';
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
grammar Shared;
|
|
2
|
+
|
|
3
|
+
game: GAME ID L_PAREN paramList? R_PAREN L_CURLY gameBody R_CURLY;
|
|
4
|
+
|
|
5
|
+
gameBody: (field SEMI)* method+
|
|
6
|
+
| (field SEMI)* method* gamePhase+;
|
|
7
|
+
|
|
8
|
+
gamePhase: PHASE L_CURLY (method)+ ORACLES COLON L_SQUARE id (COMMA id)* R_SQUARE SEMI R_CURLY;
|
|
9
|
+
|
|
10
|
+
field: variable (EQUALS expression)?;
|
|
11
|
+
|
|
12
|
+
initializedField: variable EQUALS expression;
|
|
13
|
+
|
|
14
|
+
method: methodSignature block;
|
|
15
|
+
|
|
16
|
+
block: L_CURLY statement* R_CURLY;
|
|
17
|
+
|
|
18
|
+
statement: type id SEMI #varDeclStatement
|
|
19
|
+
| type lvalue EQUALS expression SEMI #varDeclWithValueStatement
|
|
20
|
+
| type lvalue SAMPLES expression SEMI #varDeclWithSampleStatement
|
|
21
|
+
| lvalue EQUALS expression SEMI #assignmentStatement
|
|
22
|
+
| lvalue SAMPLES expression SEMI #sampleStatement
|
|
23
|
+
| expression L_PAREN argList? R_PAREN SEMI #functionCallStatement
|
|
24
|
+
| RETURN expression SEMI #returnStatement
|
|
25
|
+
| IF L_PAREN expression R_PAREN block (ELSE IF L_PAREN expression R_PAREN block )* (ELSE block )? #ifStatement
|
|
26
|
+
| FOR L_PAREN INTTYPE id EQUALS expression TO expression R_PAREN block #numericForStatement
|
|
27
|
+
| FOR L_PAREN type id IN expression R_PAREN block #genericForStatement
|
|
28
|
+
;
|
|
29
|
+
|
|
30
|
+
lvalue:
|
|
31
|
+
(id | parameterizedGame) (PERIOD id | L_SQUARE expression R_SQUARE)*;
|
|
32
|
+
|
|
33
|
+
methodSignature: type id L_PAREN paramList? R_PAREN;
|
|
34
|
+
|
|
35
|
+
paramList: variable (COMMA variable)*;
|
|
36
|
+
|
|
37
|
+
expression:
|
|
38
|
+
expression L_PAREN argList? R_PAREN #fnCallExp
|
|
39
|
+
| expression L_SQUARE integerExpression COLON integerExpression R_SQUARE #sliceExp
|
|
40
|
+
| NOT expression #notExp
|
|
41
|
+
| VBAR expression VBAR #sizeExp
|
|
42
|
+
|
|
43
|
+
| expression TIMES expression #multiplyExp
|
|
44
|
+
| expression DIVIDE expression #divideExp
|
|
45
|
+
| SUBTRACT expression #minusExp
|
|
46
|
+
| expression PLUS expression #addExp
|
|
47
|
+
| expression SUBTRACT expression #subtractExp
|
|
48
|
+
| expression EQUALSCOMPARE expression #equalsExp
|
|
49
|
+
| expression NOTEQUALS expression #notEqualsExp
|
|
50
|
+
| expression R_ANGLE expression # gtExp
|
|
51
|
+
| expression L_ANGLE expression # ltExp
|
|
52
|
+
| expression GEQ expression #geqExp
|
|
53
|
+
| expression LEQ expression #leqExp
|
|
54
|
+
| expression IN expression #inExp
|
|
55
|
+
| expression SUBSETS expression #subsetsExp
|
|
56
|
+
|
|
57
|
+
| expression AND expression #andExp
|
|
58
|
+
| expression OR expression #orExp
|
|
59
|
+
| expression UNION expression #unionExp
|
|
60
|
+
| expression BACKSLASH expression #setMinusExp
|
|
61
|
+
|
|
62
|
+
| lvalue # lvalueExp
|
|
63
|
+
| L_SQUARE (expression (COMMA expression)*)? R_SQUARE #createTupleExp
|
|
64
|
+
| L_CURLY (expression (COMMA expression)*)? R_CURLY #createSetExp
|
|
65
|
+
| type #typeExp
|
|
66
|
+
| BINARYNUM #binaryNumExp
|
|
67
|
+
| INT #intExp
|
|
68
|
+
| bool #boolExp
|
|
69
|
+
| NONE #noneExp
|
|
70
|
+
| L_PAREN expression R_PAREN #parenExp
|
|
71
|
+
;
|
|
72
|
+
|
|
73
|
+
argList: expression (COMMA expression)*;
|
|
74
|
+
|
|
75
|
+
variable: type id;
|
|
76
|
+
|
|
77
|
+
parameterizedGame: ID L_PAREN argList? R_PAREN;
|
|
78
|
+
|
|
79
|
+
type: type QUESTION #optionalType
|
|
80
|
+
| set #setType
|
|
81
|
+
| BOOL #boolType
|
|
82
|
+
| VOID #voidType
|
|
83
|
+
| MAP L_ANGLE type COMMA type R_ANGLE #mapType
|
|
84
|
+
| ARRAY L_ANGLE type COMMA integerExpression R_ANGLE #arrayType
|
|
85
|
+
| INTTYPE #intType
|
|
86
|
+
| type (TIMES type)+ #productType
|
|
87
|
+
| bitstring #bitStringType
|
|
88
|
+
| lvalue # lvalueType
|
|
89
|
+
;
|
|
90
|
+
|
|
91
|
+
integerExpression
|
|
92
|
+
: integerExpression TIMES integerExpression
|
|
93
|
+
| integerExpression DIVIDE integerExpression
|
|
94
|
+
| integerExpression PLUS integerExpression
|
|
95
|
+
| integerExpression SUBTRACT integerExpression
|
|
96
|
+
| lvalue
|
|
97
|
+
| INT
|
|
98
|
+
| BINARYNUM
|
|
99
|
+
| L_PAREN integerExpression R_PAREN
|
|
100
|
+
;
|
|
101
|
+
|
|
102
|
+
bitstring: BITSTRING L_ANGLE integerExpression R_ANGLE | BITSTRING;
|
|
103
|
+
|
|
104
|
+
set: SET L_ANGLE type R_ANGLE | SET;
|
|
105
|
+
|
|
106
|
+
bool: TRUE | FALSE;
|
|
107
|
+
|
|
108
|
+
moduleImport: IMPORT FILESTRING (AS ID)? SEMI;
|
|
109
|
+
|
|
110
|
+
id: ID | IN;
|
|
111
|
+
|
|
112
|
+
L_CURLY: '{';
|
|
113
|
+
R_CURLY: '}';
|
|
114
|
+
L_SQUARE: '[';
|
|
115
|
+
R_SQUARE: ']';
|
|
116
|
+
L_PAREN: '(';
|
|
117
|
+
R_PAREN: ')';
|
|
118
|
+
L_ANGLE: '<';
|
|
119
|
+
R_ANGLE: '>';
|
|
120
|
+
SEMI: ';';
|
|
121
|
+
COLON: ':';
|
|
122
|
+
COMMA: ',';
|
|
123
|
+
PERIOD: '.';
|
|
124
|
+
TIMES: '*';
|
|
125
|
+
EQUALS: '=';
|
|
126
|
+
PLUS: '+';
|
|
127
|
+
SUBTRACT: '-';
|
|
128
|
+
DIVIDE: '/';
|
|
129
|
+
QUESTION: '?';
|
|
130
|
+
EQUALSCOMPARE: '==';
|
|
131
|
+
NOTEQUALS: '!=';
|
|
132
|
+
GEQ: '>=';
|
|
133
|
+
LEQ: '<=';
|
|
134
|
+
OR: '||';
|
|
135
|
+
SAMPLES: '<-';
|
|
136
|
+
AND: '&&';
|
|
137
|
+
BACKSLASH: '\\';
|
|
138
|
+
NOT: '!';
|
|
139
|
+
VBAR: '|';
|
|
140
|
+
|
|
141
|
+
SET: 'Set';
|
|
142
|
+
BOOL: 'Bool';
|
|
143
|
+
VOID: 'Void';
|
|
144
|
+
INTTYPE: 'Int';
|
|
145
|
+
VOID: 'Void';
|
|
146
|
+
MAP: 'Map';
|
|
147
|
+
RETURN: 'return';
|
|
148
|
+
IMPORT: 'import';
|
|
149
|
+
BITSTRING: 'BitString';
|
|
150
|
+
ARRAY: 'Array';
|
|
151
|
+
PRIMITIVE: 'Primitive';
|
|
152
|
+
SUBSETS: 'subsets';
|
|
153
|
+
IF: 'if';
|
|
154
|
+
FOR: 'for';
|
|
155
|
+
TO: 'to';
|
|
156
|
+
IN: 'in';
|
|
157
|
+
UNION: 'union';
|
|
158
|
+
GAME: 'Game';
|
|
159
|
+
EXPORT: 'export';
|
|
160
|
+
AS: 'as';
|
|
161
|
+
PHASE: 'Phase';
|
|
162
|
+
ORACLES: 'oracles';
|
|
163
|
+
ELSE: 'else';
|
|
164
|
+
NONE: 'None';
|
|
165
|
+
|
|
166
|
+
TRUE: 'true';
|
|
167
|
+
FALSE: 'false';
|
|
168
|
+
|
|
169
|
+
BINARYNUM: '0b'[01]+ ;
|
|
170
|
+
INT: [0-9]+ ;
|
|
171
|
+
ID: [a-zA-Z_$][a-zA-Z_0-9$]* ;
|
|
172
|
+
WS: [ \t\r\n]+ -> skip ;
|
|
173
|
+
LINE_COMMENT : '//' .*? '\r'? '\n' -> skip ;
|
|
174
|
+
FILESTRING: '\''[-0-9a-zA-Z_$/.=>< ]+'\'' ;
|