lightphe 0.0.25__tar.gz → 0.0.26__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 (59) hide show
  1. {lightphe-0.0.25 → lightphe-0.0.26}/PKG-INFO +87 -27
  2. {lightphe-0.0.25 → lightphe-0.0.26}/README.md +86 -26
  3. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/__init__.py +71 -5
  4. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/key_validator.py +6 -0
  5. lightphe-0.0.26/lightphe/cryptosystems/CastagnosLaguillaumie.py +390 -0
  6. lightphe-0.0.26/lightphe/cryptosystems/IshaiPaskin.py +264 -0
  7. lightphe-0.0.26/lightphe/cryptosystems/JoyeLibert.py +227 -0
  8. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Algorithm.py +3 -0
  9. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Ciphertext.py +11 -0
  10. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Homomorphic.py +13 -1
  11. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Tensor.py +3 -0
  12. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/PKG-INFO +87 -27
  13. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/SOURCES.txt +6 -0
  14. {lightphe-0.0.25 → lightphe-0.0.26}/setup.py +1 -1
  15. lightphe-0.0.26/tests/test_castagnoslaguillaumie.py +88 -0
  16. lightphe-0.0.26/tests/test_ishaipaskin.py +216 -0
  17. lightphe-0.0.26/tests/test_joyelibert.py +107 -0
  18. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_key_validator.py +3 -0
  19. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_paillier.py +6 -0
  20. {lightphe-0.0.25 → lightphe-0.0.26}/LICENSE +0 -0
  21. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/__init__.py +0 -0
  22. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/logger.py +0 -0
  23. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/phe_utils.py +0 -0
  24. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/Benaloh.py +0 -0
  25. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/BonehGohNissim.py +0 -0
  26. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/DamgardJurik.py +0 -0
  27. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/ElGamal.py +0 -0
  28. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/EllipticCurveElGamal.py +0 -0
  29. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/GoldwasserMicali.py +0 -0
  30. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/NaccacheStern.py +0 -0
  31. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/OkamotoUchiyama.py +0 -0
  32. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/Paillier.py +0 -0
  33. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/RSA.py +0 -0
  34. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/SanderYoungYung.py +0 -0
  35. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/__init__.py +0 -0
  36. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/__init__.py +0 -0
  37. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/dependency_links.txt +0 -0
  38. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/requires.txt +0 -0
  39. {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/top_level.txt +0 -0
  40. {lightphe-0.0.25 → lightphe-0.0.26}/requirements.txt +0 -0
  41. {lightphe-0.0.25 → lightphe-0.0.26}/setup.cfg +0 -0
  42. {lightphe-0.0.25 → lightphe-0.0.26}/tests/__init__.py +0 -0
  43. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_benaloh.py +0 -0
  44. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_bonehgohnissim.py +0 -0
  45. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_ciphertexts.py +0 -0
  46. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_cloud.py +0 -0
  47. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_damgard.py +0 -0
  48. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_elgamal.py +0 -0
  49. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_ellipticcurveelgamal.py +0 -0
  50. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_exporting_keys.py +0 -0
  51. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_goldwasser.py +0 -0
  52. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_keys.py +0 -0
  53. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_large_keys.py +0 -0
  54. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_naccache.py +0 -0
  55. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_okamoto.py +0 -0
  56. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_rsa.py +0 -0
  57. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_salary.py +0 -0
  58. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_sanderyoungyung.py +0 -0
  59. {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_tensors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightphe
3
- Version: 0.0.25
3
+ Version: 0.0.26
4
4
  Summary: A Lightweight Partially Homomorphic Encryption Library for Python
5
5
  Home-page: https://github.com/serengil/LightPHE
6
6
  Author: Sefik Ilkin Serengil
@@ -20,23 +20,14 @@ License-File: LICENSE
20
20
 
21
21
  [![PyPI Downloads](https://static.pepy.tech/personalized-badge/lightphe?period=total&units=international_system&left_color=grey&right_color=blue&left_text=downloads)](https://pepy.tech/project/lightphe)
22
22
  [![Stars](https://img.shields.io/github/stars/serengil/LightPHE?color=yellow&style=flat&label=%E2%AD%90%20stars)](https://github.com/serengil/LightPHE/stargazers)
23
- [![Tests](https://github.com/serengil/LightPHE/actions/workflows/tests.yml/badge.svg)](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
24
23
  [![License](http://img.shields.io/:license-MIT-green.svg?style=flat)](https://github.com/serengil/LightPHE/blob/master/LICENSE)
25
- [![arXiv](https://img.shields.io/badge/arXiv-2408.05219-b31b1b.svg?logo=arXiv)](https://arxiv.org/abs/2408.05219)
26
-
27
- [![Blog](https://img.shields.io/:blog-sefiks.com-blue.svg?style=flat&logo=wordpress)](https://sefiks.com)
28
- [![YouTube](https://img.shields.io/:youtube-@sefiks-red.svg?style=flat&logo=youtube)](https://www.youtube.com/@sefiks?sub_confirmation=1)
29
- [![Twitter](https://img.shields.io/:follow-@serengil-blue.svg?style=flat&logo=x)](https://twitter.com/intent/user?screen_name=serengil)
30
-
31
- [![Patreon](https://img.shields.io/:become-patron-f96854.svg?style=flat&logo=patreon)](https://www.patreon.com/serengil?repo=lightphe)
32
- [![GitHub Sponsors](https://img.shields.io/github/sponsors/serengil?logo=GitHub&color=lightgray)](https://github.com/sponsors/serengil)
33
- [![Buy Me a Coffee](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://buymeacoffee.com/serengil)
24
+ [![DOI](http://img.shields.io/:DOI-10.3390/sym18050832-blue.svg?style=flat)](https://www.mdpi.com/2073-8994/18/5/832)
34
25
 
35
26
  </div>
36
27
 
37
28
  <p align="center"><img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/phi.png" width="200" height="240"></p>
38
29
 
39
- LightPHE is a lightweight homomorphic encryption library for python supporting various partially and somewhat homomorphic encryptions schemes such as [`RSA`](https://sefiks.com/2023/03/06/a-step-by-step-partially-homomorphic-encryption-example-with-rsa-in-python/), [`ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Exponential ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Elliptic Curve ElGamal`](https://sefiks.com/2018/08/21/elliptic-curve-elgamal-encryption/) ([`Weierstrass`](https://sefiks.com/2016/03/13/the-math-behind-elliptic-curve-cryptography/), [`Koblitz`](sefiks.com/2016/03/13/the-math-behind-elliptic-curves-over-binary-field/) and [`Edwards`](https://sefiks.com/2018/12/19/a-gentle-introduction-to-edwards-curves/) forms), [`Paillier`](https://sefiks.com/2023/04/03/a-step-by-step-partially-homomorphic-encryption-example-with-paillier-in-python/), [`Damgard-Jurik`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-damgard-jurik-in-python/), [`Okamoto–Uchiyama`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-okamoto-uchiyama-in-python/), [`Benaloh`](https://sefiks.com/2023/10/06/a-step-by-step-partially-homomorphic-encryption-example-with-benaloh-in-python-from-scratch/), [`Naccache–Stern`](https://sefiks.com/2023/10/26/a-step-by-step-partially-homomorphic-encryption-example-with-naccache-stern-in-python/), [`Goldwasser–Micali`](https://sefiks.com/2023/10/27/a-step-by-step-partially-homomorphic-encryption-example-with-goldwasser-micali-in-python/), [`Sander-Young-Yung`](https://sefiks.com/2026/04/02/a-step-by-step-partially-homomorphic-sander-young-yung-example-in-python/), [`Boneh-Goh-Nissim`](https://sefiks.com/2026/04/02/a-step-by-step-somewhat-homomorphic-encryption-example-with-boneh-goh-nissim-in-python/).
30
+ LightPHE is a lightweight homomorphic encryption library for python supporting various partially and somewhat homomorphic encryptions schemes such as [`RSA`](https://sefiks.com/2023/03/06/a-step-by-step-partially-homomorphic-encryption-example-with-rsa-in-python/), [`ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Exponential ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Elliptic Curve ElGamal`](https://sefiks.com/2018/08/21/elliptic-curve-elgamal-encryption/) ([`Weierstrass`](https://sefiks.com/2016/03/13/the-math-behind-elliptic-curve-cryptography/), [`Koblitz`](sefiks.com/2016/03/13/the-math-behind-elliptic-curves-over-binary-field/) and [`Edwards`](https://sefiks.com/2018/12/19/a-gentle-introduction-to-edwards-curves/) forms), [`Paillier`](https://sefiks.com/2023/04/03/a-step-by-step-partially-homomorphic-encryption-example-with-paillier-in-python/), [`Damgard-Jurik`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-damgard-jurik-in-python/), [`Okamoto–Uchiyama`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-okamoto-uchiyama-in-python/), [`Benaloh`](https://sefiks.com/2023/10/06/a-step-by-step-partially-homomorphic-encryption-example-with-benaloh-in-python-from-scratch/), [`Naccache–Stern`](https://sefiks.com/2023/10/26/a-step-by-step-partially-homomorphic-encryption-example-with-naccache-stern-in-python/), [`Goldwasser–Micali`](https://sefiks.com/2023/10/27/a-step-by-step-partially-homomorphic-encryption-example-with-goldwasser-micali-in-python/), [`Sander-Young-Yung`](https://sefiks.com/2026/04/02/a-step-by-step-partially-homomorphic-sander-young-yung-example-in-python/), [`Boneh-Goh-Nissim`](https://sefiks.com/2026/04/02/a-step-by-step-somewhat-homomorphic-encryption-example-with-boneh-goh-nissim-in-python/), `Joye-Libert`, `Castagnos-Laguillaumie`, `Ishai-Paskin`.
40
31
 
41
32
  # Partially vs Fully Homomorphic Encryption
42
33
 
@@ -67,20 +58,23 @@ from lightphe import LightPHE
67
58
 
68
59
  In summary, LightPHE is covering following algorithms and these are partially homomorphic and somewhat homomorphic with respect to the operations mentioned in the following table.
69
60
 
70
- | Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Scalar Multiplication | Bitwise-XOR Homomorphic | Bitwise-AND Homomorphic | Regeneration<br>of Ciphertext |
71
- | --- | --- | --- | --- | --- | --- | --- |
72
- | RSA | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
73
- | ElGamal | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
74
- | Exponential ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
75
- | Elliptic Curve ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
76
- | Paillier | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
77
- | Damgard-Jurik | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
78
- | Benaloh | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
79
- | Naccache-Stern | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
80
- | Okamoto-Uchiyama | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
81
- | Goldwasser-Micali | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
82
- | Sander-Young-Yung | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
83
- | Boneh-Goh-Nissim | 1️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ |
61
+ | Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Scalar Multiplication | Bitwise-XOR Homomorphic | Bitwise-AND Homomorphic | Regeneration<br>of Ciphertext | Decision Tree<br>Evaluation |
62
+ | --- | --- | --- | --- | --- | --- | --- | --- |
63
+ | RSA | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
64
+ | ElGamal | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
65
+ | Exponential ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
66
+ | Elliptic Curve ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
67
+ | Paillier | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
68
+ | Damgard-Jurik | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
69
+ | Benaloh | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
70
+ | Naccache-Stern | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
71
+ | Okamoto-Uchiyama | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
72
+ | Joye-Libert | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
73
+ | Castagnos-Laguillaumie | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
74
+ | Ishai-Paskin | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
75
+ | Goldwasser-Micali | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ |
76
+ | Sander-Young-Yung | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
77
+ | Boneh-Goh-Nissim | 1️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
84
78
 
85
79
  # Building cryptosystem
86
80
 
@@ -100,6 +94,9 @@ algorithms = [
100
94
  "EllipticCurve-ElGamal",
101
95
  "Sander-Young-Yung",
102
96
  "Boneh-Goh-Nissim",
97
+ "Joye-Libert",
98
+ "Castagnos-Laguillaumie",
99
+ "Ishai-Paskin",
103
100
  ]
104
101
 
105
102
  cs = LightPHE(algorithm_name = algorithms[0])
@@ -186,6 +183,58 @@ Each curve in LightPHE has a specific order, which is carefully chosen to balanc
186
183
 
187
184
  See [`curves`](https://github.com/serengil/LightECC#supported-curves) page for a list of all supported forms, curves and their details.
188
185
 
186
+ ### Decision Trees
187
+
188
+ Ishai-Paskin solves a different problem than the algorithms above. Suppose a bank has a secret decision tree that decides a customer's credit limit, and a customer has private yes / no answers. The bank does not want to reveal its tree, and the customer does not want to reveal their answers. With Ishai-Paskin, the customer sends encrypted answers, the bank runs its tree on them without seeing them, and only the customer can decrypt the result. The customer learns the credit limit but not the rest of the tree.
189
+
190
+ Let the bank's tree be the following, where questions are numbered 0, 1 and 2 and leaves are credit limits in thousand dollars.
191
+
192
+ ```
193
+ Q0: has stable income?
194
+ /no \yes
195
+ Q2: owns a house? Q1: has existing debt?
196
+ /no \yes /no \yes
197
+ 0 5 20 Q2: owns a house?
198
+ /no \yes
199
+ 5 10
200
+ ```
201
+
202
+ Each question is written as a tuple of `(question number, what to do if no, what to do if yes)`, and leaves are plain integers. So, the tree above becomes:
203
+
204
+ ```python
205
+ credit_limit_tree = (0, (2, 0, 5), (1, 20, (2, 5, 10)))
206
+ ```
207
+
208
+ Then, the customer and the bank run the following steps.
209
+
210
+ ```python
211
+ # customer builds the cryptosystem and keeps the private key
212
+ customer_cs = LightPHE(algorithm_name = "Ishai-Paskin")
213
+
214
+ # customer shares only the public key with the bank
215
+ customer_cs.export_keys(target_file = "public.txt", public = True)
216
+
217
+ # customer's answers: stable income = yes, existing debt = yes, owns a house = no
218
+ answers = [1, 1, 0]
219
+
220
+ # customer encrypts the answers and sends them to the bank. depth is the maximum
221
+ # number of questions on a path of the tree, the bank should share this value
222
+ encrypted_answers = customer_cs.encrypt_decision_tree_input(bits = answers, depth = 3)
223
+
224
+ # bank builds its own cryptosystem with the customer's public key
225
+ bank_cs = LightPHE(algorithm_name = "Ishai-Paskin", key_file = "public.txt")
226
+
227
+ # bank runs its tree on encrypted answers and sends the result back to the customer
228
+ encrypted_limit = bank_cs.evaluate_decision_tree(
229
+ tree = credit_limit_tree, encrypted_input = encrypted_answers
230
+ )
231
+
232
+ # customer decrypts the result - only the customer has the private key
233
+ assert customer_cs.decrypt(encrypted_limit) == 5
234
+ ```
235
+
236
+ The size of the result grows with the depth of the tree, not with the number of its nodes. Still, each extra level makes the computation noticeably slower, so this is practical for shallow trees.
237
+
189
238
  ### Vector Embeddings
190
239
 
191
240
  LightPHE supports homomorphic encryption on vector embeddings. This is useful in privacy-preserving machine learning, secure aggregation, and confidential data processing.
@@ -227,6 +276,17 @@ All PRs are more than welcome! If you are planning to contribute a large patch,
227
276
 
228
277
  You should be able run `make test` and `make lint` commands successfully before committing. Once a PR is created, GitHub test workflow will be run automatically and unit test results will be available in [GitHub actions](https://github.com/serengil/LightPHE/actions/workflows/tests.yml) before approval.
229
278
 
279
+ ## LightPHE Ecosystem
280
+
281
+ `LightPHE` is available across multiple programming languages with consistent APIs and native performance for each ecosystem. Choose the port that fits your stack:
282
+
283
+ | Language | Repository | Ecosystem Focus |
284
+ | :--- | :--- | :--- |
285
+ | **Python** | [`lightphe`](https://github.com/serengil/lightphe) | AI, Research & Prototyping |
286
+ | **Go** | [`lightphe-go`](https://github.com/serengil/lightphe-go) | Cloud-Native & High-Throughput Microservices |
287
+ | **Java** | [`lightphe4j`](https://github.com/serengil/lightphe4j) | Enterprise, Banking & Legacy Systems |
288
+ | **TypeScript** | [`lightphe-ts`](https://github.com/serengil/lightphe-ts) | Client-Side Privacy & Node.js Backend |
289
+
230
290
  # Support
231
291
 
232
292
  There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏
@@ -248,7 +308,7 @@ Also, your company's logo will be shown on README on GitHub if you become sponso
248
308
  Please cite LightPHE in your publications if it helps your research. Here is its BibTex entry:
249
309
 
250
310
  ```BibTeX
251
- @article{sym18050832,
311
+ @article{lightphe,
252
312
  title = {Sustainable Cryptography: Carbon Asymmetry in Partially Homomorphic Encryption in the Cloud},
253
313
  author = {Ozpinar, Alper and Serengil, Sefik Ilkin},
254
314
  journal = {Symmetry},
@@ -4,23 +4,14 @@
4
4
 
5
5
  [![PyPI Downloads](https://static.pepy.tech/personalized-badge/lightphe?period=total&units=international_system&left_color=grey&right_color=blue&left_text=downloads)](https://pepy.tech/project/lightphe)
6
6
  [![Stars](https://img.shields.io/github/stars/serengil/LightPHE?color=yellow&style=flat&label=%E2%AD%90%20stars)](https://github.com/serengil/LightPHE/stargazers)
7
- [![Tests](https://github.com/serengil/LightPHE/actions/workflows/tests.yml/badge.svg)](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
8
7
  [![License](http://img.shields.io/:license-MIT-green.svg?style=flat)](https://github.com/serengil/LightPHE/blob/master/LICENSE)
9
- [![arXiv](https://img.shields.io/badge/arXiv-2408.05219-b31b1b.svg?logo=arXiv)](https://arxiv.org/abs/2408.05219)
10
-
11
- [![Blog](https://img.shields.io/:blog-sefiks.com-blue.svg?style=flat&logo=wordpress)](https://sefiks.com)
12
- [![YouTube](https://img.shields.io/:youtube-@sefiks-red.svg?style=flat&logo=youtube)](https://www.youtube.com/@sefiks?sub_confirmation=1)
13
- [![Twitter](https://img.shields.io/:follow-@serengil-blue.svg?style=flat&logo=x)](https://twitter.com/intent/user?screen_name=serengil)
14
-
15
- [![Patreon](https://img.shields.io/:become-patron-f96854.svg?style=flat&logo=patreon)](https://www.patreon.com/serengil?repo=lightphe)
16
- [![GitHub Sponsors](https://img.shields.io/github/sponsors/serengil?logo=GitHub&color=lightgray)](https://github.com/sponsors/serengil)
17
- [![Buy Me a Coffee](https://img.shields.io/badge/-buy_me_a%C2%A0coffee-gray?logo=buy-me-a-coffee)](https://buymeacoffee.com/serengil)
8
+ [![DOI](http://img.shields.io/:DOI-10.3390/sym18050832-blue.svg?style=flat)](https://www.mdpi.com/2073-8994/18/5/832)
18
9
 
19
10
  </div>
20
11
 
21
12
  <p align="center"><img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/phi.png" width="200" height="240"></p>
22
13
 
23
- LightPHE is a lightweight homomorphic encryption library for python supporting various partially and somewhat homomorphic encryptions schemes such as [`RSA`](https://sefiks.com/2023/03/06/a-step-by-step-partially-homomorphic-encryption-example-with-rsa-in-python/), [`ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Exponential ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Elliptic Curve ElGamal`](https://sefiks.com/2018/08/21/elliptic-curve-elgamal-encryption/) ([`Weierstrass`](https://sefiks.com/2016/03/13/the-math-behind-elliptic-curve-cryptography/), [`Koblitz`](sefiks.com/2016/03/13/the-math-behind-elliptic-curves-over-binary-field/) and [`Edwards`](https://sefiks.com/2018/12/19/a-gentle-introduction-to-edwards-curves/) forms), [`Paillier`](https://sefiks.com/2023/04/03/a-step-by-step-partially-homomorphic-encryption-example-with-paillier-in-python/), [`Damgard-Jurik`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-damgard-jurik-in-python/), [`Okamoto–Uchiyama`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-okamoto-uchiyama-in-python/), [`Benaloh`](https://sefiks.com/2023/10/06/a-step-by-step-partially-homomorphic-encryption-example-with-benaloh-in-python-from-scratch/), [`Naccache–Stern`](https://sefiks.com/2023/10/26/a-step-by-step-partially-homomorphic-encryption-example-with-naccache-stern-in-python/), [`Goldwasser–Micali`](https://sefiks.com/2023/10/27/a-step-by-step-partially-homomorphic-encryption-example-with-goldwasser-micali-in-python/), [`Sander-Young-Yung`](https://sefiks.com/2026/04/02/a-step-by-step-partially-homomorphic-sander-young-yung-example-in-python/), [`Boneh-Goh-Nissim`](https://sefiks.com/2026/04/02/a-step-by-step-somewhat-homomorphic-encryption-example-with-boneh-goh-nissim-in-python/).
14
+ LightPHE is a lightweight homomorphic encryption library for python supporting various partially and somewhat homomorphic encryptions schemes such as [`RSA`](https://sefiks.com/2023/03/06/a-step-by-step-partially-homomorphic-encryption-example-with-rsa-in-python/), [`ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Exponential ElGamal`](https://sefiks.com/2023/03/27/a-step-by-step-partially-homomorphic-encryption-example-with-elgamal-in-python/), [`Elliptic Curve ElGamal`](https://sefiks.com/2018/08/21/elliptic-curve-elgamal-encryption/) ([`Weierstrass`](https://sefiks.com/2016/03/13/the-math-behind-elliptic-curve-cryptography/), [`Koblitz`](sefiks.com/2016/03/13/the-math-behind-elliptic-curves-over-binary-field/) and [`Edwards`](https://sefiks.com/2018/12/19/a-gentle-introduction-to-edwards-curves/) forms), [`Paillier`](https://sefiks.com/2023/04/03/a-step-by-step-partially-homomorphic-encryption-example-with-paillier-in-python/), [`Damgard-Jurik`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-damgard-jurik-in-python/), [`Okamoto–Uchiyama`](https://sefiks.com/2023/10/20/a-step-by-step-partially-homomorphic-encryption-example-with-okamoto-uchiyama-in-python/), [`Benaloh`](https://sefiks.com/2023/10/06/a-step-by-step-partially-homomorphic-encryption-example-with-benaloh-in-python-from-scratch/), [`Naccache–Stern`](https://sefiks.com/2023/10/26/a-step-by-step-partially-homomorphic-encryption-example-with-naccache-stern-in-python/), [`Goldwasser–Micali`](https://sefiks.com/2023/10/27/a-step-by-step-partially-homomorphic-encryption-example-with-goldwasser-micali-in-python/), [`Sander-Young-Yung`](https://sefiks.com/2026/04/02/a-step-by-step-partially-homomorphic-sander-young-yung-example-in-python/), [`Boneh-Goh-Nissim`](https://sefiks.com/2026/04/02/a-step-by-step-somewhat-homomorphic-encryption-example-with-boneh-goh-nissim-in-python/), `Joye-Libert`, `Castagnos-Laguillaumie`, `Ishai-Paskin`.
24
15
 
25
16
  # Partially vs Fully Homomorphic Encryption
26
17
 
@@ -51,20 +42,23 @@ from lightphe import LightPHE
51
42
 
52
43
  In summary, LightPHE is covering following algorithms and these are partially homomorphic and somewhat homomorphic with respect to the operations mentioned in the following table.
53
44
 
54
- | Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Scalar Multiplication | Bitwise-XOR Homomorphic | Bitwise-AND Homomorphic | Regeneration<br>of Ciphertext |
55
- | --- | --- | --- | --- | --- | --- | --- |
56
- | RSA | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
57
- | ElGamal | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
58
- | Exponential ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
59
- | Elliptic Curve ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
60
- | Paillier | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
61
- | Damgard-Jurik | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
62
- | Benaloh | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
63
- | Naccache-Stern | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
64
- | Okamoto-Uchiyama | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
65
- | Goldwasser-Micali | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
66
- | Sander-Young-Yung | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
67
- | Boneh-Goh-Nissim | 1️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ |
45
+ | Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Scalar Multiplication | Bitwise-XOR Homomorphic | Bitwise-AND Homomorphic | Regeneration<br>of Ciphertext | Decision Tree<br>Evaluation |
46
+ | --- | --- | --- | --- | --- | --- | --- | --- |
47
+ | RSA | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
48
+ | ElGamal | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
49
+ | Exponential ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
50
+ | Elliptic Curve ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
51
+ | Paillier | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
52
+ | Damgard-Jurik | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
53
+ | Benaloh | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
54
+ | Naccache-Stern | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
55
+ | Okamoto-Uchiyama | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
56
+ | Joye-Libert | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
57
+ | Castagnos-Laguillaumie | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
58
+ | Ishai-Paskin | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |
59
+ | Goldwasser-Micali | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ |
60
+ | Sander-Young-Yung | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ |
61
+ | Boneh-Goh-Nissim | 1️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
68
62
 
69
63
  # Building cryptosystem
70
64
 
@@ -84,6 +78,9 @@ algorithms = [
84
78
  "EllipticCurve-ElGamal",
85
79
  "Sander-Young-Yung",
86
80
  "Boneh-Goh-Nissim",
81
+ "Joye-Libert",
82
+ "Castagnos-Laguillaumie",
83
+ "Ishai-Paskin",
87
84
  ]
88
85
 
89
86
  cs = LightPHE(algorithm_name = algorithms[0])
@@ -170,6 +167,58 @@ Each curve in LightPHE has a specific order, which is carefully chosen to balanc
170
167
 
171
168
  See [`curves`](https://github.com/serengil/LightECC#supported-curves) page for a list of all supported forms, curves and their details.
172
169
 
170
+ ### Decision Trees
171
+
172
+ Ishai-Paskin solves a different problem than the algorithms above. Suppose a bank has a secret decision tree that decides a customer's credit limit, and a customer has private yes / no answers. The bank does not want to reveal its tree, and the customer does not want to reveal their answers. With Ishai-Paskin, the customer sends encrypted answers, the bank runs its tree on them without seeing them, and only the customer can decrypt the result. The customer learns the credit limit but not the rest of the tree.
173
+
174
+ Let the bank's tree be the following, where questions are numbered 0, 1 and 2 and leaves are credit limits in thousand dollars.
175
+
176
+ ```
177
+ Q0: has stable income?
178
+ /no \yes
179
+ Q2: owns a house? Q1: has existing debt?
180
+ /no \yes /no \yes
181
+ 0 5 20 Q2: owns a house?
182
+ /no \yes
183
+ 5 10
184
+ ```
185
+
186
+ Each question is written as a tuple of `(question number, what to do if no, what to do if yes)`, and leaves are plain integers. So, the tree above becomes:
187
+
188
+ ```python
189
+ credit_limit_tree = (0, (2, 0, 5), (1, 20, (2, 5, 10)))
190
+ ```
191
+
192
+ Then, the customer and the bank run the following steps.
193
+
194
+ ```python
195
+ # customer builds the cryptosystem and keeps the private key
196
+ customer_cs = LightPHE(algorithm_name = "Ishai-Paskin")
197
+
198
+ # customer shares only the public key with the bank
199
+ customer_cs.export_keys(target_file = "public.txt", public = True)
200
+
201
+ # customer's answers: stable income = yes, existing debt = yes, owns a house = no
202
+ answers = [1, 1, 0]
203
+
204
+ # customer encrypts the answers and sends them to the bank. depth is the maximum
205
+ # number of questions on a path of the tree, the bank should share this value
206
+ encrypted_answers = customer_cs.encrypt_decision_tree_input(bits = answers, depth = 3)
207
+
208
+ # bank builds its own cryptosystem with the customer's public key
209
+ bank_cs = LightPHE(algorithm_name = "Ishai-Paskin", key_file = "public.txt")
210
+
211
+ # bank runs its tree on encrypted answers and sends the result back to the customer
212
+ encrypted_limit = bank_cs.evaluate_decision_tree(
213
+ tree = credit_limit_tree, encrypted_input = encrypted_answers
214
+ )
215
+
216
+ # customer decrypts the result - only the customer has the private key
217
+ assert customer_cs.decrypt(encrypted_limit) == 5
218
+ ```
219
+
220
+ The size of the result grows with the depth of the tree, not with the number of its nodes. Still, each extra level makes the computation noticeably slower, so this is practical for shallow trees.
221
+
173
222
  ### Vector Embeddings
174
223
 
175
224
  LightPHE supports homomorphic encryption on vector embeddings. This is useful in privacy-preserving machine learning, secure aggregation, and confidential data processing.
@@ -211,6 +260,17 @@ All PRs are more than welcome! If you are planning to contribute a large patch,
211
260
 
212
261
  You should be able run `make test` and `make lint` commands successfully before committing. Once a PR is created, GitHub test workflow will be run automatically and unit test results will be available in [GitHub actions](https://github.com/serengil/LightPHE/actions/workflows/tests.yml) before approval.
213
262
 
263
+ ## LightPHE Ecosystem
264
+
265
+ `LightPHE` is available across multiple programming languages with consistent APIs and native performance for each ecosystem. Choose the port that fits your stack:
266
+
267
+ | Language | Repository | Ecosystem Focus |
268
+ | :--- | :--- | :--- |
269
+ | **Python** | [`lightphe`](https://github.com/serengil/lightphe) | AI, Research & Prototyping |
270
+ | **Go** | [`lightphe-go`](https://github.com/serengil/lightphe-go) | Cloud-Native & High-Throughput Microservices |
271
+ | **Java** | [`lightphe4j`](https://github.com/serengil/lightphe4j) | Enterprise, Banking & Legacy Systems |
272
+ | **TypeScript** | [`lightphe-ts`](https://github.com/serengil/lightphe-ts) | Client-Side Privacy & Node.js Backend |
273
+
214
274
  # Support
215
275
 
216
276
  There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏
@@ -232,7 +292,7 @@ Also, your company's logo will be shown on README on GitHub if you become sponso
232
292
  Please cite LightPHE in your publications if it helps your research. Here is its BibTex entry:
233
293
 
234
294
  ```BibTeX
235
- @article{sym18050832,
295
+ @article{lightphe,
236
296
  title = {Sustainable Cryptography: Carbon Asymmetry in Partially Homomorphic Encryption in the Cloud},
237
297
  author = {Ozpinar, Alper and Serengil, Sefik Ilkin},
238
298
  journal = {Symmetry},
@@ -31,12 +31,15 @@ from lightphe.cryptosystems.GoldwasserMicali import GoldwasserMicali
31
31
  from lightphe.cryptosystems.EllipticCurveElGamal import EllipticCurveElGamal
32
32
  from lightphe.cryptosystems.SanderYoungYung import SanderYoungYung
33
33
  from lightphe.cryptosystems.BonehGohNissim import BonehGohNissim
34
+ from lightphe.cryptosystems.JoyeLibert import JoyeLibert, FLOAT_NOT_SUPPORTED_MSG
35
+ from lightphe.cryptosystems.CastagnosLaguillaumie import CastagnosLaguillaumie
36
+ from lightphe.cryptosystems.IshaiPaskin import IshaiPaskin
34
37
 
35
38
  # pylint: disable=eval-used, simplifiable-if-expression, too-few-public-methods
36
39
 
37
40
  logger = Logger(module="lightphe/__init__.py")
38
41
 
39
- VERSION = "0.0.25"
42
+ VERSION = "0.0.26"
40
43
 
41
44
 
42
45
  class LightPHE:
@@ -60,6 +63,7 @@ class LightPHE:
60
63
  algorithm_name (str): RSA | ElGamal | Exponential-ElGamal | EllipticCurve-ElGamal
61
64
  | Paillier | Damgard-Jurik | Okamoto-Uchiyama | Benaloh | Naccache-Stern
62
65
  | Goldwasser-Micali | Sander-Young-Yung | Boneh-Goh-Nissim
66
+ | Joye-Libert | Castagnos-Laguillaumie | Ishai-Paskin
63
67
  keys (dict): optional private-public key pair
64
68
  key_file (str): if keys were exported already, you can load them into cryptosystem
65
69
  key_size (int): key size in bits
@@ -78,8 +82,8 @@ class LightPHE:
78
82
  plaintext_limit (int, optional): Upper bound for plaintext values.
79
83
  This parameter is only used if `algorithm_name` is 'Benaloh'.
80
84
  max_tries (int): maximum attempts to generate keys. Default is 10000.
81
- RSA, Benaloh, Naccache-Stern and Goldwasser-Micali algorithms
82
- need multiple attempts to generate valid keys. Will be discarded
85
+ RSA, Benaloh, Naccache-Stern, Goldwasser-Micali, Boneh-Goh-Nissim,
86
+ Joye-Libert and Castagnos-Laguillaumie algorithms need multiple attempts to generate valid keys. Will be discarded
83
87
  for other algorithms.
84
88
  """
85
89
  self.algorithm_name = algorithm_name
@@ -123,6 +127,9 @@ class LightPHE:
123
127
  EllipticCurveElGamal,
124
128
  SanderYoungYung,
125
129
  BonehGohNissim,
130
+ JoyeLibert,
131
+ CastagnosLaguillaumie,
132
+ IshaiPaskin,
126
133
  ]:
127
134
  """
128
135
  Build a cryptosystem among partially homomorphic algorithms
@@ -130,6 +137,7 @@ class LightPHE:
130
137
  algorithm_name (str): RSA | ElGamal | Exponential-ElGamal | EllipticCurve-ElGamal
131
138
  | Paillier | Damgard-Jurik | Okamoto-Uchiyama | Benaloh | Naccache-Stern
132
139
  | Goldwasser-Micali | Edwards-ElGamal | Sander-Young-Yung | Boneh-Goh-Nissim
140
+ | Joye-Libert | Castagnos-Laguillaumie | Ishai-Paskin
133
141
  Default is Paillier.
134
142
  keys (dict): optional private-public key pair
135
143
  key_file (str): if keys are exported, you can load them into cryptosystem
@@ -145,8 +153,8 @@ class LightPHE:
145
153
  plaintext_limit (int, optional): Upper bound for plaintext values.
146
154
  This parameter is only used if `algorithm_name` is 'Benaloh'.
147
155
  max_tries (int): maximum attempts to generate keys. Default is 10000.
148
- RSA, Benaloh, Naccache-Stern and Goldwasser-Micali algorithms
149
- need multiple attempts to generate valid keys. Will be discarded
156
+ RSA, Benaloh, Naccache-Stern, Goldwasser-Micali, Boneh-Goh-Nissim,
157
+ Joye-Libert and Castagnos-Laguillaumie algorithms need multiple attempts to generate valid keys. Will be discarded
150
158
  for other algorithms.
151
159
  Returns
152
160
  cryptosystem
@@ -185,6 +193,14 @@ class LightPHE:
185
193
  )
186
194
  elif algorithm_name == Algorithm.BonehGohNissim:
187
195
  cs = BonehGohNissim(keys=keys, key_size=key_size, max_tries=max_tries)
196
+ elif algorithm_name == Algorithm.JoyeLibert:
197
+ cs = JoyeLibert(keys=keys, key_size=key_size, max_tries=max_tries)
198
+ elif algorithm_name == Algorithm.CastagnosLaguillaumie:
199
+ cs = CastagnosLaguillaumie(
200
+ keys=keys, key_size=key_size, max_tries=max_tries
201
+ )
202
+ elif algorithm_name == Algorithm.IshaiPaskin:
203
+ cs = IshaiPaskin(keys=keys, key_size=key_size)
188
204
  else:
189
205
  raise ValueError(f"unimplemented algorithm - {algorithm_name}")
190
206
  return cs
@@ -207,6 +223,9 @@ class LightPHE:
207
223
  # then encrypt tensors
208
224
  return self.__encrypt_tensors(tensor=plaintext, silent=silent)
209
225
 
226
+ if isinstance(plaintext, float) and self.algorithm_name == Algorithm.JoyeLibert:
227
+ raise ValueError(FLOAT_NOT_SUPPORTED_MSG)
228
+
210
229
  ciphertext = self.cs.encrypt(
211
230
  plaintext=phe_utils.normalize_input(
212
231
  value=plaintext, modulo=self.cs.plaintext_modulo
@@ -330,6 +349,53 @@ class LightPHE:
330
349
  plain_tensor.append(m)
331
350
  return plain_tensor
332
351
 
352
+ def encrypt_decision_tree_input(
353
+ self, bits: List[int], depth: int
354
+ ) -> List[List[int]]:
355
+ """
356
+ Encrypt input bits (answers to the questions) of a decision tree.
357
+ Only supported by Ishai-Paskin.
358
+ Args:
359
+ bits (list of int): input bits x_0, x_1, ... each 0 or 1
360
+ depth (int): maximum number of decisions on a path of the decision tree
361
+ Returns:
362
+ encrypted input (list of list of int): to be sent to the tree owner
363
+ """
364
+ if self.cs.keys.get("public_key") is None:
365
+ raise ValueError("You must have public key to perform encryption")
366
+
367
+ return self.cs.encrypt_decision_tree_input(bits=bits, depth=depth)
368
+
369
+ def evaluate_decision_tree(
370
+ self, tree: Union[int, tuple], encrypted_input: List[List[int]]
371
+ ) -> Ciphertext:
372
+ """
373
+ Evaluate a decision tree on encrypted input.
374
+ Private key is not required. Only supported by Ishai-Paskin.
375
+ Args:
376
+ tree (int or tuple): leaf (int) or decision node
377
+ (variable_index, tree_if_0, tree_if_1)
378
+ encrypted_input (list of list of int): output of encrypt_decision_tree_input
379
+ Returns:
380
+ ciphertext (Ciphertext): encrypted output of the tree
381
+ """
382
+ if self.cs.keys.get("public_key") is None:
383
+ raise ValueError(
384
+ "You must have public key to perform decision tree evaluation"
385
+ )
386
+
387
+ output = self.cs.evaluate_decision_tree(
388
+ tree=tree, encrypted_input=encrypted_input
389
+ )
390
+
391
+ public_keys = self.cs.keys.copy()
392
+ if public_keys.get("private_key") is not None:
393
+ del public_keys["private_key"]
394
+
395
+ return Ciphertext(
396
+ algorithm_name=self.algorithm_name, keys=public_keys, value=output
397
+ )
398
+
333
399
  def regenerate_ciphertext(self, ciphertext: Ciphertext) -> Ciphertext:
334
400
  """
335
401
  Generate a different ciphertext belonging to same plaintext
@@ -13,6 +13,9 @@ from lightphe.cryptosystems.NaccacheStern import NaccacheStern
13
13
  from lightphe.cryptosystems.GoldwasserMicali import GoldwasserMicali
14
14
  from lightphe.cryptosystems.SanderYoungYung import SanderYoungYung
15
15
  from lightphe.cryptosystems.BonehGohNissim import BonehGohNissim
16
+ from lightphe.cryptosystems.JoyeLibert import JoyeLibert
17
+ from lightphe.cryptosystems.CastagnosLaguillaumie import CastagnosLaguillaumie
18
+ from lightphe.cryptosystems.IshaiPaskin import IshaiPaskin
16
19
 
17
20
 
18
21
  # Map user-facing algorithm names to the class that owns the REQUIRED_KEYS spec.
@@ -31,6 +34,9 @@ _ALGORITHM_TO_CLASS: Dict[str, Type[Homomorphic]] = {
31
34
  Algorithm.GoldwasserMicali: GoldwasserMicali,
32
35
  Algorithm.SanderYoungYung: SanderYoungYung,
33
36
  Algorithm.BonehGohNissim: BonehGohNissim,
37
+ Algorithm.JoyeLibert: JoyeLibert,
38
+ Algorithm.CastagnosLaguillaumie: CastagnosLaguillaumie,
39
+ Algorithm.IshaiPaskin: IshaiPaskin,
34
40
  }
35
41
 
36
42