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.
- {lightphe-0.0.25 → lightphe-0.0.26}/PKG-INFO +87 -27
- {lightphe-0.0.25 → lightphe-0.0.26}/README.md +86 -26
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/__init__.py +71 -5
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/key_validator.py +6 -0
- lightphe-0.0.26/lightphe/cryptosystems/CastagnosLaguillaumie.py +390 -0
- lightphe-0.0.26/lightphe/cryptosystems/IshaiPaskin.py +264 -0
- lightphe-0.0.26/lightphe/cryptosystems/JoyeLibert.py +227 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Algorithm.py +3 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Ciphertext.py +11 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Homomorphic.py +13 -1
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/Tensor.py +3 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/PKG-INFO +87 -27
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/SOURCES.txt +6 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/setup.py +1 -1
- lightphe-0.0.26/tests/test_castagnoslaguillaumie.py +88 -0
- lightphe-0.0.26/tests/test_ishaipaskin.py +216 -0
- lightphe-0.0.26/tests/test_joyelibert.py +107 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_key_validator.py +3 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_paillier.py +6 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/LICENSE +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/__init__.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/logger.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/commons/phe_utils.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/Benaloh.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/BonehGohNissim.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/DamgardJurik.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/ElGamal.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/EllipticCurveElGamal.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/GoldwasserMicali.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/NaccacheStern.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/OkamotoUchiyama.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/Paillier.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/RSA.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/SanderYoungYung.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/cryptosystems/__init__.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe/models/__init__.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/dependency_links.txt +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/requires.txt +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/lightphe.egg-info/top_level.txt +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/requirements.txt +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/setup.cfg +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/__init__.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_benaloh.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_bonehgohnissim.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_ciphertexts.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_cloud.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_damgard.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_elgamal.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_ellipticcurveelgamal.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_exporting_keys.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_goldwasser.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_keys.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_large_keys.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_naccache.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_okamoto.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_rsa.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_salary.py +0 -0
- {lightphe-0.0.25 → lightphe-0.0.26}/tests/test_sanderyoungyung.py +0 -0
- {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.
|
|
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
|
[](https://pepy.tech/project/lightphe)
|
|
22
22
|
[](https://github.com/serengil/LightPHE/stargazers)
|
|
23
|
-
[](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
|
|
24
23
|
[](https://github.com/serengil/LightPHE/blob/master/LICENSE)
|
|
25
|
-
[](https://sefiks.com)
|
|
28
|
-
[](https://www.youtube.com/@sefiks?sub_confirmation=1)
|
|
29
|
-
[](https://twitter.com/intent/user?screen_name=serengil)
|
|
30
|
-
|
|
31
|
-
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
32
|
-
[](https://github.com/sponsors/serengil)
|
|
33
|
-
[](https://buymeacoffee.com/serengil)
|
|
24
|
+
[](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
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
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{
|
|
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
|
[](https://pepy.tech/project/lightphe)
|
|
6
6
|
[](https://github.com/serengil/LightPHE/stargazers)
|
|
7
|
-
[](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
|
|
8
7
|
[](https://github.com/serengil/LightPHE/blob/master/LICENSE)
|
|
9
|
-
[](https://sefiks.com)
|
|
12
|
-
[](https://www.youtube.com/@sefiks?sub_confirmation=1)
|
|
13
|
-
[](https://twitter.com/intent/user?screen_name=serengil)
|
|
14
|
-
|
|
15
|
-
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
16
|
-
[](https://github.com/sponsors/serengil)
|
|
17
|
-
[](https://buymeacoffee.com/serengil)
|
|
8
|
+
[](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
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
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{
|
|
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.
|
|
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
|
|
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
|
|
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
|
|