fhe-cli 1.3.1__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.
Files changed (44) hide show
  1. fhe_cli-1.3.1/LICENSE +21 -0
  2. fhe_cli-1.3.1/MANIFEST.in +11 -0
  3. fhe_cli-1.3.1/PKG-INFO +280 -0
  4. fhe_cli-1.3.1/README.md +245 -0
  5. fhe_cli-1.3.1/fhe_cli.egg-info/PKG-INFO +280 -0
  6. fhe_cli-1.3.1/fhe_cli.egg-info/SOURCES.txt +42 -0
  7. fhe_cli-1.3.1/fhe_cli.egg-info/dependency_links.txt +1 -0
  8. fhe_cli-1.3.1/fhe_cli.egg-info/entry_points.txt +2 -0
  9. fhe_cli-1.3.1/fhe_cli.egg-info/requires.txt +5 -0
  10. fhe_cli-1.3.1/fhe_cli.egg-info/top_level.txt +1 -0
  11. fhe_cli-1.3.1/fhecli/__init__.py +5 -0
  12. fhe_cli-1.3.1/fhecli/__main__.py +6 -0
  13. fhe_cli-1.3.1/fhecli/cli.py +220 -0
  14. fhe_cli-1.3.1/fhecli/data/info.toml +77 -0
  15. fhe_cli-1.3.1/fhecli/data/originals/ex10_ckks_bonus.py +84 -0
  16. fhe_cli-1.3.1/fhecli/data/originals/ex1_cesar.py +92 -0
  17. fhe_cli-1.3.1/fhecli/data/originals/ex2_xor_malleability.py +102 -0
  18. fhe_cli-1.3.1/fhecli/data/originals/ex3_fernet_tamper.py +92 -0
  19. fhe_cli-1.3.1/fhecli/data/originals/ex4_modpow.py +73 -0
  20. fhe_cli-1.3.1/fhecli/data/originals/ex5_modinv.py +77 -0
  21. fhe_cli-1.3.1/fhecli/data/originals/ex6_paillier_keygen.py +85 -0
  22. fhe_cli-1.3.1/fhecli/data/originals/ex7_paillier_enc_dec.py +118 -0
  23. fhe_cli-1.3.1/fhecli/data/originals/ex8_paillier_homomorphic.py +144 -0
  24. fhe_cli-1.3.1/fhecli/data/originals/ex9_scoring_paillier.py +143 -0
  25. fhe_cli-1.3.1/fhecli/data/solutions/ex10_ckks_bonus.sol +8 -0
  26. fhe_cli-1.3.1/fhecli/data/solutions/ex1_cesar.sol +6 -0
  27. fhe_cli-1.3.1/fhecli/data/solutions/ex2_xor_malleability.sol +7 -0
  28. fhe_cli-1.3.1/fhecli/data/solutions/ex3_fernet_tamper.sol +7 -0
  29. fhe_cli-1.3.1/fhecli/data/solutions/ex4_modpow.sol +5 -0
  30. fhe_cli-1.3.1/fhecli/data/solutions/ex5_modinv.sol +6 -0
  31. fhe_cli-1.3.1/fhecli/data/solutions/ex6_paillier_keygen.sol +8 -0
  32. fhe_cli-1.3.1/fhecli/data/solutions/ex7_paillier_enc_dec.sol +11 -0
  33. fhe_cli-1.3.1/fhecli/data/solutions/ex8_paillier_homomorphic.sol +12 -0
  34. fhe_cli-1.3.1/fhecli/data/solutions/ex9_scoring_paillier.sol +15 -0
  35. fhe_cli-1.3.1/fhecli/info.py +46 -0
  36. fhe_cli-1.3.1/fhecli/resources.py +28 -0
  37. fhe_cli-1.3.1/fhecli/runner.py +72 -0
  38. fhe_cli-1.3.1/fhecli/solutions.py +30 -0
  39. fhe_cli-1.3.1/fhecli/ui.py +70 -0
  40. fhe_cli-1.3.1/fhecli/watch.py +116 -0
  41. fhe_cli-1.3.1/fhecli/workspace.py +58 -0
  42. fhe_cli-1.3.1/pyproject.toml +71 -0
  43. fhe_cli-1.3.1/setup.cfg +4 -0
  44. fhe_cli-1.3.1/tests/test_cli.py +340 -0
fhe_cli-1.3.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ravin THILAGARASA, Thomas GRUNDSZTEJN
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,11 @@
1
+ # Contenu du sdist : code du paquet, données embarquées, tests de l'outil.
2
+ include README.md LICENSE
3
+ graft fhecli/data
4
+ graft tests
5
+ # Jamais dans les archives publiées : solutions en clair, espace de travail
6
+ # de développement, script d'encodage (inutile sans les solutions en clair).
7
+ prune solutions_src
8
+ prune exercises
9
+ prune scripts
10
+ exclude fhecli.toml pytest.ini requirements.txt
11
+ global-exclude *.py[cod] __pycache__
fhe_cli-1.3.1/PKG-INFO ADDED
@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.4
2
+ Name: fhe-cli
3
+ Version: 1.3.1
4
+ Summary: Atelier d'exercices en ligne de commande, à la rustlings : chiffrement classique et chiffrement homomorphe (FHE)
5
+ Author: Ravin THILAGARASA, Thomas GRUNDSZTEJN
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Defl3ct-941/Scoring_FHE
8
+ Project-URL: Source, https://github.com/Defl3ct-941/Scoring_FHE/tree/main/03_cas_pratiques/fhe-exercices-cli
9
+ Project-URL: Issues, https://github.com/Defl3ct-941/Scoring_FHE/issues
10
+ Project-URL: GitLab, https://gitlab.securechat.fr/esgi/5a/Scoring_FHE
11
+ Project-URL: Changelog, https://github.com/Defl3ct-941/Scoring_FHE/blob/main/CHANGELOG.md
12
+ Keywords: fhe,chiffrement homomorphe,homomorphic encryption,cryptographie,cryptography,exercices,rustlings,enseignement,scoring
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Natural Language :: French
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Programming Language :: Python :: 3.15
25
+ Classifier: Topic :: Education
26
+ Classifier: Topic :: Security :: Cryptography
27
+ Requires-Python: >=3.11
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: pytest<10,>=9.2
31
+ Requires-Dist: cryptography<51,>=50.0
32
+ Provides-Extra: ckks
33
+ Requires-Dist: tenseal<0.4,>=0.3.16; extra == "ckks"
34
+ Dynamic: license-file
35
+
36
+ # fhecli : atelier CLI de chiffrement classique et FHE
37
+
38
+ Un atelier d'exercices en ligne de commande, inspiré de
39
+ [rustlings](https://github.com/rust-lang/rustlings) : vous éditez les fichiers
40
+ d'exercice dans votre propre éditeur, avec votre propre environnement Python,
41
+ et un petit outil (`fhecli`) surveille vos fichiers et relance les tests à
42
+ chaque sauvegarde.
43
+
44
+ Il accompagne le cours « Scoring financier sur données chiffrées via FHE »
45
+ (FYC, ESGI) : c'est la même progression pédagogique que l'atelier web du
46
+ projet, adaptée pour tourner directement dans votre terminal.
47
+
48
+ > **Version actuelle : 3 exercices.** Seul le module A (chiffrement
49
+ > classique) est publié pour le moment. Les modules suivants (arithmétique
50
+ > modulaire, Paillier from scratch, scoring chiffré, bonus CKKS) arriveront
51
+ > dans une prochaine mise à jour.
52
+
53
+ ## Installation
54
+
55
+ Python 3.11 ou plus récent est requis.
56
+
57
+ ```bash
58
+ python -m venv .venv
59
+ # Windows
60
+ .venv\Scripts\activate
61
+ # macOS / Linux
62
+ source .venv/bin/activate
63
+
64
+ pip install fhe-cli
65
+ fhecli init # crée le dossier ./fhe-exercices avec les exercices
66
+ cd fhe-exercices
67
+ fhecli watch
68
+ ```
69
+
70
+ Le paquet s'installe sous le nom **`fhe-cli`** ; la commande et le module
71
+ Python restent `fhecli`.
72
+
73
+ `fhecli init [dossier]` crée un **espace de travail** : le dossier
74
+ `exercises/` (vos fichiers), un `pytest.ini` et un fichier marqueur
75
+ `fhecli.toml`. Les commandes de `fhecli` retrouvent cet espace depuis n'importe
76
+ quel sous-dossier. `fhecli init` refuse d'écraser un espace existant.
77
+
78
+ ### Sans Python : exécutable autonome
79
+
80
+ Pour chaque OS, un exécutable unique embarque tout (Python, `fhecli`,
81
+ `pytest`, `cryptography` et les exercices) : **aucune installation de Python
82
+ n'est nécessaire**. Téléchargez celui de votre système
83
+ (`fhecli-<version>-windows-x86_64.exe`, `-linux-x86_64`, `-macos-arm64` ou
84
+ `-macos-x86_64`), puis :
85
+
86
+ ```bash
87
+ # Windows (PowerShell)
88
+ . hecli-1.2.0-windows-x86_64.exe init
89
+ # macOS / Linux
90
+ chmod +x fhecli-1.2.0-linux-x86_64
91
+ ./fhecli-1.2.0-linux-x86_64 init
92
+ ```
93
+
94
+ Renommez-le en `fhecli` (ou `fhecli.exe`) et placez-le dans un dossier du
95
+ `PATH` pour l'utiliser comme dans les exemples ci-dessous. Le code et les
96
+ solutions y sont embarqués compressés, jamais en clair. Sous macOS, au premier
97
+ lancement, autorisez le binaire dans Réglages système > Confidentialité et
98
+ sécurité (il n'est pas signé).
99
+
100
+ ## Utilisation
101
+
102
+ ### Mode guidé (recommandé pour commencer)
103
+
104
+ ```bash
105
+ fhecli watch
106
+ ```
107
+
108
+ Affiche l'exercice courant, relance ses tests à chaque fois que vous
109
+ sauvegardez le fichier, et passe automatiquement au suivant une fois qu'il est
110
+ résolu (en proposant alors d'afficher la solution de référence pour comparer).
111
+ Ctrl+C pour quitter à tout moment : rien n'est perdu, vos fichiers restent sur
112
+ le disque.
113
+
114
+ ### Autres commandes
115
+
116
+ ```bash
117
+ fhecli list # vue d'ensemble des exercices et de leur statut
118
+ fhecli run ex1_cesar # lance les tests d'un seul exercice
119
+ fhecli hint ex1_cesar # affiche un indice ciblé
120
+ fhecli solution ex1_cesar # affiche la solution (une fois l'exercice résolu)
121
+ fhecli reset ex1_cesar # remet CET exercice à son énoncé de départ (avec confirmation)
122
+ fhecli reset --all # remet TOUS les exercices à leur énoncé de départ (avec confirmation)
123
+ fhecli reset --all -y # idem, sans confirmation
124
+ fhecli --version
125
+ ```
126
+
127
+ Codes de sortie de `fhecli run` : `0` exercice résolu, `1` tests en échec
128
+ (ou erreur), `2` tests OK mais ligne `# I AM NOT DONE` encore présente.
129
+
130
+ Vous pouvez aussi lancer les tests vous-même avec `python -m pytest` depuis
131
+ l'espace de travail : le `pytest.ini` fourni collecte bien les exercices.
132
+
133
+ ## Comment marche un exercice
134
+
135
+ Chaque exercice est un unique fichier `.py` dans `exercises/`, qui contient
136
+ tout :
137
+
138
+ 1. Un docstring en haut du fichier avec l'énoncé complet (contexte,
139
+ formules, ce qu'il faut implémenter, indices).
140
+ 2. Une ligne `# I AM NOT DONE` juste après : tant qu'elle est présente,
141
+ l'exercice est considéré comme « pas terminé », même si les tests passent
142
+ déjà. **Retirez-la vous-même** une fois satisfait de votre solution :
143
+ c'est un geste délibérément manuel, pour vous forcer à vraiment valider
144
+ votre travail.
145
+ 3. La ou les fonctions à compléter (marquées `raise NotImplementedError`).
146
+ 4. Une section de tests en bas du fichier (à ne pas modifier), exécutée par
147
+ `pytest` à chaque `fhecli run` / `fhecli watch`.
148
+
149
+ ## Solutions
150
+
151
+ La solution de référence d'un exercice est **verrouillée** tant que
152
+ l'exercice n'est pas résolu : `fhecli solution` ne l'affiche qu'une fois que
153
+ les tests passent **et** que la ligne `# I AM NOT DONE` a été retirée.
154
+
155
+ Dans le paquet, les solutions ne sont pas stockées en clair : elles sont
156
+ compressées et encodées (zlib + base64). C'est une **dissuasion**, pour
157
+ éviter de tomber sur la correction par hasard en fouillant le dossier du
158
+ paquet, **pas une protection** : rien n'empêche quelqu'un de déterminé de les
159
+ décoder. Le vrai garde-fou reste pédagogique.
160
+
161
+ ## Progression (dans l'ordre suivi par `fhecli watch`)
162
+
163
+ | # | Exercice | Catégorie |
164
+ |---|----------|-----------|
165
+ | 1 | ex1_cesar | A. Chiffrement classique |
166
+ | 2 | ex2_xor_malleability | A. Chiffrement classique |
167
+ | 3 | ex3_fernet_tamper | A. Chiffrement classique |
168
+ | 4 | ex4_modpow | B. Briques mathématiques |
169
+ | 5 | ex5_modinv | B. Briques mathématiques |
170
+ | 6 | ex6_paillier_keygen | C. Paillier, pas à pas |
171
+ | 7 | ex7_paillier_enc_dec | C. Paillier, pas à pas |
172
+ | 8 | ex8_paillier_homomorphic | C. Paillier, pas à pas |
173
+ | 9 | ex9_scoring_paillier | D. Scoring chiffré |
174
+ | 10 | ex10_ckks_bonus | E. Bonus : FHE réel avec CKKS |
175
+
176
+ Le parcours va du chiffrement classique (où tout calcul sur le chiffré est
177
+ impossible) à Paillier reconstruit à la main, puis à un score bancaire chiffré
178
+ de bout en bout, et enfin à un vrai calcul FHE avec CKKS.
179
+
180
+ Le bonus **ex10 (CKKS)** s'appuie sur [TenSEAL](https://github.com/OpenMined/TenSEAL),
181
+ une dépendance native qui n'est pas installée par défaut (et qui n'est pas
182
+ embarquée dans les exécutables autonomes). Pour le faire :
183
+
184
+ ```bash
185
+ pip install "fhe-cli[ckks]"
186
+ ```
187
+
188
+ Sans TenSEAL, les tests de l'ex10 sont simplement ignorés (skipped).
189
+
190
+ ## Développement (depuis le dépôt Scoring FHE)
191
+
192
+ Le dossier `03_cas_pratiques/fhe-exercices-cli` du dépôt est lui-même un
193
+ espace de travail (il contient `fhecli.toml`, `pytest.ini` et `exercises/`) :
194
+
195
+ ```bash
196
+ cd 03_cas_pratiques/fhe-exercices-cli
197
+ python -m venv .venv
198
+ .venv\Scripts\activate # macOS / Linux : source .venv/bin/activate
199
+ pip install -e .
200
+ fhecli watch
201
+ python -m pytest tests -q # tests de l'outil lui-même
202
+ ```
203
+
204
+ Avant de commiter : `fhecli reset --all -y`, pour ne jamais versionner de
205
+ réponses dans `exercises/`.
206
+
207
+ ```
208
+ fhe-exercices-cli/
209
+ ├── pyproject.toml # empaquetage (PyPI), point d'entrée `fhecli`
210
+ ├── LICENSE, MANIFEST.in
211
+ ├── fhecli/ # le paquet
212
+ │ ├── cli.py # commandes : init, watch, list, run, hint, solution, reset
213
+ │ ├── workspace.py # création et recherche de l'espace de travail
214
+ │ ├── watch.py # boucle de surveillance des fichiers
215
+ │ ├── runner.py # exécution de pytest en sous-processus isolé
216
+ │ ├── info.py, resources.py # liste des exercices, accès aux données du paquet
217
+ │ ├── solutions.py # encodage / décodage des solutions
218
+ │ ├── ui.py # couleurs, UTF-8, confirmations
219
+ │ └── data/ # embarqué dans le paquet (lecture seule)
220
+ │ ├── info.toml # métadonnées des exercices (titre, catégorie, indice)
221
+ │ ├── originals/ # énoncés d'origine (fhecli init / reset)
222
+ │ └── solutions/ # solutions ENCODÉES (.sol)
223
+ ├── solutions_src/ # solutions en clair : dans le dépôt, JAMAIS dans la wheel ni le sdist
224
+ ├── scripts/ # encode_solutions.py, build_binary.py, check_binary.py
225
+ ├── packaging/ # spécification PyInstaller (exécutables autonomes)
226
+ ├── tests/ # tests automatisés de l'outil
227
+ ├── exercises/ # espace de travail de développement
228
+ ├── fhecli.toml, pytest.ini # marqueur et configuration de cet espace
229
+ └── requirements.txt
230
+ ```
231
+
232
+ Après toute modification d'une solution dans `solutions_src/` :
233
+
234
+ ```bash
235
+ python scripts/encode_solutions.py
236
+ ```
237
+
238
+ Construire le paquet (sans le publier) :
239
+
240
+ ```bash
241
+ python -m pip install build
242
+ python -m build # dist/fhe_cli-<version>-py3-none-any.whl et .tar.gz
243
+ ```
244
+
245
+ ## Exécutables, CI et publication
246
+
247
+ Construire et vérifier l'exécutable de l'OS courant (PyInstaller ne fait pas
248
+ de compilation croisée) :
249
+
250
+ ```bash
251
+ pip install -e . pyinstaller
252
+ python scripts/build_binary.py # dist/fhecli-<version>-<os>-<arch>[.exe]
253
+ ```
254
+
255
+ `scripts/build_binary.py` lance ensuite `scripts/check_binary.py`, qui
256
+ rejoue le parcours d'un étudiant avec le binaire seul (sans Python dans le
257
+ `PATH`) et vérifie qu'aucun source, aucune solution ni aucun énoncé n'apparaît
258
+ en clair dans le fichier.
259
+
260
+ La CI **GitHub Actions** (`.github/workflows/fhecli.yml`) fait tout cela
261
+ automatiquement : tests sur Linux, Windows et macOS (Python 3.11 et 3.15),
262
+ exécutables Windows, Linux, macOS arm64 et macOS x86_64, wheel et sdist.
263
+
264
+ Pour publier une version : mettre à jour `fhecli.__version__` et le
265
+ CHANGELOG, puis pousser un tag `fhecli-vX.Y.Z` (il doit correspondre à la
266
+ version). GitHub crée alors une release avec les exécutables et publie sur
267
+ PyPI. Une version publiée sur PyPI ne peut pas être republiée : en cas de
268
+ problème, publier la version suivante.
269
+
270
+ Configuration à faire une seule fois :
271
+
272
+ - PyPI, « trusted publishing » : sur pypi.org, ajouter un *pending publisher*
273
+ pour le projet `fhecli` (dépôt `Defl3ct-941/Scoring_FHE`, workflow
274
+ `fhecli.yml`, environnement `pypi`), et créer l'environnement `pypi` dans
275
+ les réglages du dépôt GitHub (limité aux tags `fhecli-v*`). Aucun jeton
276
+ API n'est nécessaire.
277
+
278
+ ## Licence
279
+
280
+ MIT, voir [LICENSE](LICENSE).
@@ -0,0 +1,245 @@
1
+ # fhecli : atelier CLI de chiffrement classique et FHE
2
+
3
+ Un atelier d'exercices en ligne de commande, inspiré de
4
+ [rustlings](https://github.com/rust-lang/rustlings) : vous éditez les fichiers
5
+ d'exercice dans votre propre éditeur, avec votre propre environnement Python,
6
+ et un petit outil (`fhecli`) surveille vos fichiers et relance les tests à
7
+ chaque sauvegarde.
8
+
9
+ Il accompagne le cours « Scoring financier sur données chiffrées via FHE »
10
+ (FYC, ESGI) : c'est la même progression pédagogique que l'atelier web du
11
+ projet, adaptée pour tourner directement dans votre terminal.
12
+
13
+ > **Version actuelle : 3 exercices.** Seul le module A (chiffrement
14
+ > classique) est publié pour le moment. Les modules suivants (arithmétique
15
+ > modulaire, Paillier from scratch, scoring chiffré, bonus CKKS) arriveront
16
+ > dans une prochaine mise à jour.
17
+
18
+ ## Installation
19
+
20
+ Python 3.11 ou plus récent est requis.
21
+
22
+ ```bash
23
+ python -m venv .venv
24
+ # Windows
25
+ .venv\Scripts\activate
26
+ # macOS / Linux
27
+ source .venv/bin/activate
28
+
29
+ pip install fhe-cli
30
+ fhecli init # crée le dossier ./fhe-exercices avec les exercices
31
+ cd fhe-exercices
32
+ fhecli watch
33
+ ```
34
+
35
+ Le paquet s'installe sous le nom **`fhe-cli`** ; la commande et le module
36
+ Python restent `fhecli`.
37
+
38
+ `fhecli init [dossier]` crée un **espace de travail** : le dossier
39
+ `exercises/` (vos fichiers), un `pytest.ini` et un fichier marqueur
40
+ `fhecli.toml`. Les commandes de `fhecli` retrouvent cet espace depuis n'importe
41
+ quel sous-dossier. `fhecli init` refuse d'écraser un espace existant.
42
+
43
+ ### Sans Python : exécutable autonome
44
+
45
+ Pour chaque OS, un exécutable unique embarque tout (Python, `fhecli`,
46
+ `pytest`, `cryptography` et les exercices) : **aucune installation de Python
47
+ n'est nécessaire**. Téléchargez celui de votre système
48
+ (`fhecli-<version>-windows-x86_64.exe`, `-linux-x86_64`, `-macos-arm64` ou
49
+ `-macos-x86_64`), puis :
50
+
51
+ ```bash
52
+ # Windows (PowerShell)
53
+ . hecli-1.2.0-windows-x86_64.exe init
54
+ # macOS / Linux
55
+ chmod +x fhecli-1.2.0-linux-x86_64
56
+ ./fhecli-1.2.0-linux-x86_64 init
57
+ ```
58
+
59
+ Renommez-le en `fhecli` (ou `fhecli.exe`) et placez-le dans un dossier du
60
+ `PATH` pour l'utiliser comme dans les exemples ci-dessous. Le code et les
61
+ solutions y sont embarqués compressés, jamais en clair. Sous macOS, au premier
62
+ lancement, autorisez le binaire dans Réglages système > Confidentialité et
63
+ sécurité (il n'est pas signé).
64
+
65
+ ## Utilisation
66
+
67
+ ### Mode guidé (recommandé pour commencer)
68
+
69
+ ```bash
70
+ fhecli watch
71
+ ```
72
+
73
+ Affiche l'exercice courant, relance ses tests à chaque fois que vous
74
+ sauvegardez le fichier, et passe automatiquement au suivant une fois qu'il est
75
+ résolu (en proposant alors d'afficher la solution de référence pour comparer).
76
+ Ctrl+C pour quitter à tout moment : rien n'est perdu, vos fichiers restent sur
77
+ le disque.
78
+
79
+ ### Autres commandes
80
+
81
+ ```bash
82
+ fhecli list # vue d'ensemble des exercices et de leur statut
83
+ fhecli run ex1_cesar # lance les tests d'un seul exercice
84
+ fhecli hint ex1_cesar # affiche un indice ciblé
85
+ fhecli solution ex1_cesar # affiche la solution (une fois l'exercice résolu)
86
+ fhecli reset ex1_cesar # remet CET exercice à son énoncé de départ (avec confirmation)
87
+ fhecli reset --all # remet TOUS les exercices à leur énoncé de départ (avec confirmation)
88
+ fhecli reset --all -y # idem, sans confirmation
89
+ fhecli --version
90
+ ```
91
+
92
+ Codes de sortie de `fhecli run` : `0` exercice résolu, `1` tests en échec
93
+ (ou erreur), `2` tests OK mais ligne `# I AM NOT DONE` encore présente.
94
+
95
+ Vous pouvez aussi lancer les tests vous-même avec `python -m pytest` depuis
96
+ l'espace de travail : le `pytest.ini` fourni collecte bien les exercices.
97
+
98
+ ## Comment marche un exercice
99
+
100
+ Chaque exercice est un unique fichier `.py` dans `exercises/`, qui contient
101
+ tout :
102
+
103
+ 1. Un docstring en haut du fichier avec l'énoncé complet (contexte,
104
+ formules, ce qu'il faut implémenter, indices).
105
+ 2. Une ligne `# I AM NOT DONE` juste après : tant qu'elle est présente,
106
+ l'exercice est considéré comme « pas terminé », même si les tests passent
107
+ déjà. **Retirez-la vous-même** une fois satisfait de votre solution :
108
+ c'est un geste délibérément manuel, pour vous forcer à vraiment valider
109
+ votre travail.
110
+ 3. La ou les fonctions à compléter (marquées `raise NotImplementedError`).
111
+ 4. Une section de tests en bas du fichier (à ne pas modifier), exécutée par
112
+ `pytest` à chaque `fhecli run` / `fhecli watch`.
113
+
114
+ ## Solutions
115
+
116
+ La solution de référence d'un exercice est **verrouillée** tant que
117
+ l'exercice n'est pas résolu : `fhecli solution` ne l'affiche qu'une fois que
118
+ les tests passent **et** que la ligne `# I AM NOT DONE` a été retirée.
119
+
120
+ Dans le paquet, les solutions ne sont pas stockées en clair : elles sont
121
+ compressées et encodées (zlib + base64). C'est une **dissuasion**, pour
122
+ éviter de tomber sur la correction par hasard en fouillant le dossier du
123
+ paquet, **pas une protection** : rien n'empêche quelqu'un de déterminé de les
124
+ décoder. Le vrai garde-fou reste pédagogique.
125
+
126
+ ## Progression (dans l'ordre suivi par `fhecli watch`)
127
+
128
+ | # | Exercice | Catégorie |
129
+ |---|----------|-----------|
130
+ | 1 | ex1_cesar | A. Chiffrement classique |
131
+ | 2 | ex2_xor_malleability | A. Chiffrement classique |
132
+ | 3 | ex3_fernet_tamper | A. Chiffrement classique |
133
+ | 4 | ex4_modpow | B. Briques mathématiques |
134
+ | 5 | ex5_modinv | B. Briques mathématiques |
135
+ | 6 | ex6_paillier_keygen | C. Paillier, pas à pas |
136
+ | 7 | ex7_paillier_enc_dec | C. Paillier, pas à pas |
137
+ | 8 | ex8_paillier_homomorphic | C. Paillier, pas à pas |
138
+ | 9 | ex9_scoring_paillier | D. Scoring chiffré |
139
+ | 10 | ex10_ckks_bonus | E. Bonus : FHE réel avec CKKS |
140
+
141
+ Le parcours va du chiffrement classique (où tout calcul sur le chiffré est
142
+ impossible) à Paillier reconstruit à la main, puis à un score bancaire chiffré
143
+ de bout en bout, et enfin à un vrai calcul FHE avec CKKS.
144
+
145
+ Le bonus **ex10 (CKKS)** s'appuie sur [TenSEAL](https://github.com/OpenMined/TenSEAL),
146
+ une dépendance native qui n'est pas installée par défaut (et qui n'est pas
147
+ embarquée dans les exécutables autonomes). Pour le faire :
148
+
149
+ ```bash
150
+ pip install "fhe-cli[ckks]"
151
+ ```
152
+
153
+ Sans TenSEAL, les tests de l'ex10 sont simplement ignorés (skipped).
154
+
155
+ ## Développement (depuis le dépôt Scoring FHE)
156
+
157
+ Le dossier `03_cas_pratiques/fhe-exercices-cli` du dépôt est lui-même un
158
+ espace de travail (il contient `fhecli.toml`, `pytest.ini` et `exercises/`) :
159
+
160
+ ```bash
161
+ cd 03_cas_pratiques/fhe-exercices-cli
162
+ python -m venv .venv
163
+ .venv\Scripts\activate # macOS / Linux : source .venv/bin/activate
164
+ pip install -e .
165
+ fhecli watch
166
+ python -m pytest tests -q # tests de l'outil lui-même
167
+ ```
168
+
169
+ Avant de commiter : `fhecli reset --all -y`, pour ne jamais versionner de
170
+ réponses dans `exercises/`.
171
+
172
+ ```
173
+ fhe-exercices-cli/
174
+ ├── pyproject.toml # empaquetage (PyPI), point d'entrée `fhecli`
175
+ ├── LICENSE, MANIFEST.in
176
+ ├── fhecli/ # le paquet
177
+ │ ├── cli.py # commandes : init, watch, list, run, hint, solution, reset
178
+ │ ├── workspace.py # création et recherche de l'espace de travail
179
+ │ ├── watch.py # boucle de surveillance des fichiers
180
+ │ ├── runner.py # exécution de pytest en sous-processus isolé
181
+ │ ├── info.py, resources.py # liste des exercices, accès aux données du paquet
182
+ │ ├── solutions.py # encodage / décodage des solutions
183
+ │ ├── ui.py # couleurs, UTF-8, confirmations
184
+ │ └── data/ # embarqué dans le paquet (lecture seule)
185
+ │ ├── info.toml # métadonnées des exercices (titre, catégorie, indice)
186
+ │ ├── originals/ # énoncés d'origine (fhecli init / reset)
187
+ │ └── solutions/ # solutions ENCODÉES (.sol)
188
+ ├── solutions_src/ # solutions en clair : dans le dépôt, JAMAIS dans la wheel ni le sdist
189
+ ├── scripts/ # encode_solutions.py, build_binary.py, check_binary.py
190
+ ├── packaging/ # spécification PyInstaller (exécutables autonomes)
191
+ ├── tests/ # tests automatisés de l'outil
192
+ ├── exercises/ # espace de travail de développement
193
+ ├── fhecli.toml, pytest.ini # marqueur et configuration de cet espace
194
+ └── requirements.txt
195
+ ```
196
+
197
+ Après toute modification d'une solution dans `solutions_src/` :
198
+
199
+ ```bash
200
+ python scripts/encode_solutions.py
201
+ ```
202
+
203
+ Construire le paquet (sans le publier) :
204
+
205
+ ```bash
206
+ python -m pip install build
207
+ python -m build # dist/fhe_cli-<version>-py3-none-any.whl et .tar.gz
208
+ ```
209
+
210
+ ## Exécutables, CI et publication
211
+
212
+ Construire et vérifier l'exécutable de l'OS courant (PyInstaller ne fait pas
213
+ de compilation croisée) :
214
+
215
+ ```bash
216
+ pip install -e . pyinstaller
217
+ python scripts/build_binary.py # dist/fhecli-<version>-<os>-<arch>[.exe]
218
+ ```
219
+
220
+ `scripts/build_binary.py` lance ensuite `scripts/check_binary.py`, qui
221
+ rejoue le parcours d'un étudiant avec le binaire seul (sans Python dans le
222
+ `PATH`) et vérifie qu'aucun source, aucune solution ni aucun énoncé n'apparaît
223
+ en clair dans le fichier.
224
+
225
+ La CI **GitHub Actions** (`.github/workflows/fhecli.yml`) fait tout cela
226
+ automatiquement : tests sur Linux, Windows et macOS (Python 3.11 et 3.15),
227
+ exécutables Windows, Linux, macOS arm64 et macOS x86_64, wheel et sdist.
228
+
229
+ Pour publier une version : mettre à jour `fhecli.__version__` et le
230
+ CHANGELOG, puis pousser un tag `fhecli-vX.Y.Z` (il doit correspondre à la
231
+ version). GitHub crée alors une release avec les exécutables et publie sur
232
+ PyPI. Une version publiée sur PyPI ne peut pas être republiée : en cas de
233
+ problème, publier la version suivante.
234
+
235
+ Configuration à faire une seule fois :
236
+
237
+ - PyPI, « trusted publishing » : sur pypi.org, ajouter un *pending publisher*
238
+ pour le projet `fhecli` (dépôt `Defl3ct-941/Scoring_FHE`, workflow
239
+ `fhecli.yml`, environnement `pypi`), et créer l'environnement `pypi` dans
240
+ les réglages du dépôt GitHub (limité aux tags `fhecli-v*`). Aucun jeton
241
+ API n'est nécessaire.
242
+
243
+ ## Licence
244
+
245
+ MIT, voir [LICENSE](LICENSE).