lightphe 0.0.24__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.24 → lightphe-0.0.26}/PKG-INFO +99 -44
  2. {lightphe-0.0.24 → lightphe-0.0.26}/README.md +98 -43
  3. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/__init__.py +71 -6
  4. {lightphe-0.0.24 → 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.24 → lightphe-0.0.26}/lightphe/cryptosystems/NaccacheStern.py +9 -7
  9. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/models/Algorithm.py +3 -0
  10. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/models/Ciphertext.py +11 -0
  11. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/models/Homomorphic.py +13 -1
  12. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/models/Tensor.py +3 -0
  13. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe.egg-info/PKG-INFO +99 -44
  14. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe.egg-info/SOURCES.txt +6 -0
  15. {lightphe-0.0.24 → lightphe-0.0.26}/setup.py +1 -1
  16. lightphe-0.0.26/tests/test_castagnoslaguillaumie.py +88 -0
  17. lightphe-0.0.26/tests/test_ishaipaskin.py +216 -0
  18. lightphe-0.0.26/tests/test_joyelibert.py +107 -0
  19. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_key_validator.py +3 -0
  20. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_naccache.py +4 -5
  21. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_paillier.py +6 -0
  22. {lightphe-0.0.24 → lightphe-0.0.26}/LICENSE +0 -0
  23. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/commons/__init__.py +0 -0
  24. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/commons/logger.py +0 -0
  25. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/commons/phe_utils.py +0 -0
  26. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/Benaloh.py +0 -0
  27. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/BonehGohNissim.py +0 -0
  28. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/DamgardJurik.py +0 -0
  29. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/ElGamal.py +0 -0
  30. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/EllipticCurveElGamal.py +0 -0
  31. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/GoldwasserMicali.py +0 -0
  32. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/OkamotoUchiyama.py +0 -0
  33. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/Paillier.py +0 -0
  34. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/RSA.py +0 -0
  35. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/SanderYoungYung.py +0 -0
  36. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/cryptosystems/__init__.py +0 -0
  37. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe/models/__init__.py +0 -0
  38. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe.egg-info/dependency_links.txt +0 -0
  39. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe.egg-info/requires.txt +0 -0
  40. {lightphe-0.0.24 → lightphe-0.0.26}/lightphe.egg-info/top_level.txt +0 -0
  41. {lightphe-0.0.24 → lightphe-0.0.26}/requirements.txt +0 -0
  42. {lightphe-0.0.24 → lightphe-0.0.26}/setup.cfg +0 -0
  43. {lightphe-0.0.24 → lightphe-0.0.26}/tests/__init__.py +0 -0
  44. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_benaloh.py +0 -0
  45. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_bonehgohnissim.py +0 -0
  46. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_ciphertexts.py +0 -0
  47. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_cloud.py +0 -0
  48. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_damgard.py +0 -0
  49. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_elgamal.py +0 -0
  50. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_ellipticcurveelgamal.py +0 -0
  51. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_exporting_keys.py +0 -0
  52. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_goldwasser.py +0 -0
  53. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_keys.py +0 -0
  54. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_large_keys.py +0 -0
  55. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_okamoto.py +0 -0
  56. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_rsa.py +0 -0
  57. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_salary.py +0 -0
  58. {lightphe-0.0.24 → lightphe-0.0.26}/tests/test_sanderyoungyung.py +0 -0
  59. {lightphe-0.0.24 → 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.24
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
 
@@ -65,22 +56,25 @@ from lightphe import LightPHE
65
56
 
66
57
  # Summary of Homomorphic Features of Different Cryptosystems in LightPHE
67
58
 
68
- In summary, LightPHE is covering following algorithms and these are partially homomorphic with respect to the operations mentioned in the following table.
69
-
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️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ |
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.
60
+
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,22 +308,17 @@ 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{serengil2024lightphe,
252
- title={LightPHE: Integrating Partially Homomorphic Encryption into Python with Extensive Cloud Environment Evaluations},
253
- author={Serengil, Sefik Ilkin and Ozpinar, Alper},
254
- journal={arXiv preprint arXiv:2408.05219},
255
- note={doi: 10.48550/arXiv.2408.05219. [Online]. Available: \url{https://arxiv.org/abs/2408.05219}},
256
- year={2025}
257
- }
258
- ```
259
-
260
- ```BibTeX
261
- @article{serengil2025vectorsimilarity,
262
- title={Encrypted Vector Similarity Computations Using Partially Homomorphic Encryption: Applications and Performance Analysis},
263
- author={Serengil, Sefik and Ozpinar, Alper},
264
- journal={arXiv preprint arXiv:2503.05850},
265
- note={doi: 10.48550/arXiv.2503.05850. [Online]. Available: \url{https://arxiv.org/abs/2503.05850}},
266
- year={2025}
311
+ @article{lightphe,
312
+ title = {Sustainable Cryptography: Carbon Asymmetry in Partially Homomorphic Encryption in the Cloud},
313
+ author = {Ozpinar, Alper and Serengil, Sefik Ilkin},
314
+ journal = {Symmetry},
315
+ volume = {18},
316
+ number = {5},
317
+ pages = {832},
318
+ url = {https://www.mdpi.com/2073-8994/18/5/832},
319
+ doi = {10.3390/sym18050832},
320
+ note = {Special Issue: Symmetry in Cryptography and Cybersecurity},
321
+ year = {2026}
267
322
  }
268
323
  ```
269
324
 
@@ -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
 
@@ -49,22 +40,25 @@ from lightphe import LightPHE
49
40
 
50
41
  # Summary of Homomorphic Features of Different Cryptosystems in LightPHE
51
42
 
52
- In summary, LightPHE is covering following algorithms and these are partially homomorphic with respect to the operations mentioned in the following table.
53
-
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️⃣ | ✅ | ✅ | ❌ | ❌ | ✅ |
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.
44
+
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,22 +292,17 @@ 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{serengil2024lightphe,
236
- title={LightPHE: Integrating Partially Homomorphic Encryption into Python with Extensive Cloud Environment Evaluations},
237
- author={Serengil, Sefik Ilkin and Ozpinar, Alper},
238
- journal={arXiv preprint arXiv:2408.05219},
239
- note={doi: 10.48550/arXiv.2408.05219. [Online]. Available: \url{https://arxiv.org/abs/2408.05219}},
240
- year={2025}
241
- }
242
- ```
243
-
244
- ```BibTeX
245
- @article{serengil2025vectorsimilarity,
246
- title={Encrypted Vector Similarity Computations Using Partially Homomorphic Encryption: Applications and Performance Analysis},
247
- author={Serengil, Sefik and Ozpinar, Alper},
248
- journal={arXiv preprint arXiv:2503.05850},
249
- note={doi: 10.48550/arXiv.2503.05850. [Online]. Available: \url{https://arxiv.org/abs/2503.05850}},
250
- year={2025}
295
+ @article{lightphe,
296
+ title = {Sustainable Cryptography: Carbon Asymmetry in Partially Homomorphic Encryption in the Cloud},
297
+ author = {Ozpinar, Alper and Serengil, Sefik Ilkin},
298
+ journal = {Symmetry},
299
+ volume = {18},
300
+ number = {5},
301
+ pages = {832},
302
+ url = {https://www.mdpi.com/2073-8994/18/5/832},
303
+ doi = {10.3390/sym18050832},
304
+ note = {Special Issue: Symmetry in Cryptography and Cybersecurity},
305
+ year = {2026}
251
306
  }
252
307
  ```
253
308
 
@@ -31,13 +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
-
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
35
37
 
36
38
  # pylint: disable=eval-used, simplifiable-if-expression, too-few-public-methods
37
39
 
38
40
  logger = Logger(module="lightphe/__init__.py")
39
41
 
40
- VERSION = "0.0.24"
42
+ VERSION = "0.0.26"
41
43
 
42
44
 
43
45
  class LightPHE:
@@ -61,6 +63,7 @@ class LightPHE:
61
63
  algorithm_name (str): RSA | ElGamal | Exponential-ElGamal | EllipticCurve-ElGamal
62
64
  | Paillier | Damgard-Jurik | Okamoto-Uchiyama | Benaloh | Naccache-Stern
63
65
  | Goldwasser-Micali | Sander-Young-Yung | Boneh-Goh-Nissim
66
+ | Joye-Libert | Castagnos-Laguillaumie | Ishai-Paskin
64
67
  keys (dict): optional private-public key pair
65
68
  key_file (str): if keys were exported already, you can load them into cryptosystem
66
69
  key_size (int): key size in bits
@@ -79,8 +82,8 @@ class LightPHE:
79
82
  plaintext_limit (int, optional): Upper bound for plaintext values.
80
83
  This parameter is only used if `algorithm_name` is 'Benaloh'.
81
84
  max_tries (int): maximum attempts to generate keys. Default is 10000.
82
- RSA, Benaloh, Naccache-Stern and Goldwasser-Micali algorithms
83
- 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
84
87
  for other algorithms.
85
88
  """
86
89
  self.algorithm_name = algorithm_name
@@ -124,6 +127,9 @@ class LightPHE:
124
127
  EllipticCurveElGamal,
125
128
  SanderYoungYung,
126
129
  BonehGohNissim,
130
+ JoyeLibert,
131
+ CastagnosLaguillaumie,
132
+ IshaiPaskin,
127
133
  ]:
128
134
  """
129
135
  Build a cryptosystem among partially homomorphic algorithms
@@ -131,6 +137,7 @@ class LightPHE:
131
137
  algorithm_name (str): RSA | ElGamal | Exponential-ElGamal | EllipticCurve-ElGamal
132
138
  | Paillier | Damgard-Jurik | Okamoto-Uchiyama | Benaloh | Naccache-Stern
133
139
  | Goldwasser-Micali | Edwards-ElGamal | Sander-Young-Yung | Boneh-Goh-Nissim
140
+ | Joye-Libert | Castagnos-Laguillaumie | Ishai-Paskin
134
141
  Default is Paillier.
135
142
  keys (dict): optional private-public key pair
136
143
  key_file (str): if keys are exported, you can load them into cryptosystem
@@ -146,8 +153,8 @@ class LightPHE:
146
153
  plaintext_limit (int, optional): Upper bound for plaintext values.
147
154
  This parameter is only used if `algorithm_name` is 'Benaloh'.
148
155
  max_tries (int): maximum attempts to generate keys. Default is 10000.
149
- RSA, Benaloh, Naccache-Stern and Goldwasser-Micali algorithms
150
- 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
151
158
  for other algorithms.
152
159
  Returns
153
160
  cryptosystem
@@ -186,6 +193,14 @@ class LightPHE:
186
193
  )
187
194
  elif algorithm_name == Algorithm.BonehGohNissim:
188
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)
189
204
  else:
190
205
  raise ValueError(f"unimplemented algorithm - {algorithm_name}")
191
206
  return cs
@@ -208,6 +223,9 @@ class LightPHE:
208
223
  # then encrypt tensors
209
224
  return self.__encrypt_tensors(tensor=plaintext, silent=silent)
210
225
 
226
+ if isinstance(plaintext, float) and self.algorithm_name == Algorithm.JoyeLibert:
227
+ raise ValueError(FLOAT_NOT_SUPPORTED_MSG)
228
+
211
229
  ciphertext = self.cs.encrypt(
212
230
  plaintext=phe_utils.normalize_input(
213
231
  value=plaintext, modulo=self.cs.plaintext_modulo
@@ -331,6 +349,53 @@ class LightPHE:
331
349
  plain_tensor.append(m)
332
350
  return plain_tensor
333
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
+
334
399
  def regenerate_ciphertext(self, ciphertext: Ciphertext) -> Ciphertext:
335
400
  """
336
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