lightphe 0.0.5__tar.gz → 0.0.7__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.5 → lightphe-0.0.7}/PKG-INFO +27 -9
- {lightphe-0.0.5 → lightphe-0.0.7}/README.md +26 -8
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/__init__.py +11 -2
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/ElGamal.py +9 -2
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/GoldwasserMicali.py +6 -1
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/OkamotoUchiyama.py +10 -7
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe.egg-info/PKG-INFO +27 -9
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe.egg-info/SOURCES.txt +2 -0
- lightphe-0.0.7/requirements.txt +2 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/setup.py +2 -1
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_cloud.py +6 -5
- lightphe-0.0.7/tests/test_exporting_keys.py +26 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/LICENSE +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/commons/__init__.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/commons/logger.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/commons/phe_utils.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/Benaloh.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/DamgardJurik.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/EllipticCurveElGamal.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/NaccacheStern.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/Paillier.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/RSA.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/cryptosystems/__init__.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/elliptic/Weierstrass.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/elliptic/__init__.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/Algorithm.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/Ciphertext.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/EllipticCurve.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/Homomorphic.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/Tensor.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe/models/__init__.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe.egg-info/dependency_links.txt +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe.egg-info/requires.txt +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/lightphe.egg-info/top_level.txt +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/setup.cfg +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/__init__.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_benaloh.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_damgard.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_elgamal.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_ellipticcurveelgamal.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_goldwasser.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_naccache.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_okamoto.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_paillier.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_rsa.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/tests/test_salary.py +0 -0
- {lightphe-0.0.5 → lightphe-0.0.7}/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.7
|
|
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
|
|
@@ -19,7 +19,7 @@ License-File: LICENSE
|
|
|
19
19
|
<div align="center">
|
|
20
20
|
|
|
21
21
|
[](https://pepy.tech/project/lightphe)
|
|
22
|
-
[](https://github.com/serengil/LightPHE/stargazers)
|
|
22
|
+
[](https://github.com/serengil/LightPHE/stargazers)
|
|
23
23
|
[](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
|
|
24
24
|
[](https://github.com/serengil/LightPHE/blob/master/LICENSE)
|
|
25
25
|
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
@@ -41,11 +41,10 @@ Even though fully homomorphic encryption (FHE) has become available in recent ti
|
|
|
41
41
|
|
|
42
42
|
- 🏎️ Notably faster
|
|
43
43
|
- 💻 Demands fewer computational resources
|
|
44
|
-
- 📏 Generating smaller ciphertexts
|
|
44
|
+
- 📏 Generating much smaller ciphertexts
|
|
45
|
+
- 🔑 Distributing much smaller keys
|
|
45
46
|
- 🧠 Well-suited for memory-constrained environments
|
|
46
47
|
- ⚖️ Strikes a favorable balance for practical use cases
|
|
47
|
-
- 🔑 Supporting encryption and decryption of vectors
|
|
48
|
-
- 🗝️ Performing homomorphic addition, homomorphic element-wise multiplication and scalar multiplication on encrypted vectors
|
|
49
48
|
|
|
50
49
|
# Installation [](https://pypi.org/project/lightphe/)
|
|
51
50
|
|
|
@@ -177,14 +176,14 @@ However, if you tried to multiply ciphertexts with RSA, or xor ciphertexts with
|
|
|
177
176
|
|
|
178
177
|
# Working with vectors
|
|
179
178
|
|
|
180
|
-
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support.
|
|
179
|
+
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support including homomorphic addition, element-wise multiplication and scalar multiplication.
|
|
181
180
|
|
|
182
181
|
```python
|
|
183
182
|
# build an additively homomorphic cryptosystem
|
|
184
183
|
cs = LightPHE(algorithm_name="Paillier")
|
|
185
184
|
|
|
186
185
|
# define plain tensors
|
|
187
|
-
t1 = [1.005, 2.05,
|
|
186
|
+
t1 = [1.005, 2.05, 3.5, 4]
|
|
188
187
|
t2 = [5, 6.2, 7.002, 8.02]
|
|
189
188
|
|
|
190
189
|
# encrypt tensors
|
|
@@ -194,13 +193,32 @@ c2 = cs.encrypt(t2)
|
|
|
194
193
|
# perform homomorphic addition
|
|
195
194
|
c3 = c1 + c2
|
|
196
195
|
|
|
196
|
+
# perform homomorphic element-wise multiplication
|
|
197
|
+
c4 = c1 * c2
|
|
198
|
+
|
|
199
|
+
# perform homomorphic scalar multiplication
|
|
200
|
+
k = 5
|
|
201
|
+
c5 = k * c1
|
|
202
|
+
|
|
197
203
|
# decrypt the addition tensor
|
|
198
204
|
t3 = cs.decrypt(c3)
|
|
199
205
|
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
# decrypt the element-wise multiplied tensor
|
|
207
|
+
t4 = cs.decrypt(c4)
|
|
208
|
+
|
|
209
|
+
# decrypt the scalar multiplied tensor
|
|
210
|
+
t5 = cs.decrypt(c5)
|
|
211
|
+
|
|
212
|
+
# data validations
|
|
213
|
+
threshold = 0.5
|
|
214
|
+
for i in range(0, len(t1)):
|
|
215
|
+
assert abs((t1[i] + t2[i]) - t3[i]) < threshold
|
|
216
|
+
assert abs((t1[i] * t2[i]) - t4[i]) < threshold
|
|
217
|
+
assert abs((t1[i] * k) - t5[i]) < threshold
|
|
202
218
|
```
|
|
203
219
|
|
|
220
|
+
Unfortunately, vector multiplication (dot product) requires both homomorphic addition and homomorphic multiplication and this cannot be done with partially homomorphic encryption algorithms.
|
|
221
|
+
|
|
204
222
|
# Contributing
|
|
205
223
|
|
|
206
224
|
All PRs are more than welcome! If you are planning to contribute a large patch, please create an issue first to get any upfront questions or design decisions out of the way first.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
5
|
[](https://pepy.tech/project/lightphe)
|
|
6
|
-
[](https://github.com/serengil/LightPHE/stargazers)
|
|
6
|
+
[](https://github.com/serengil/LightPHE/stargazers)
|
|
7
7
|
[](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
|
|
8
8
|
[](https://github.com/serengil/LightPHE/blob/master/LICENSE)
|
|
9
9
|
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
@@ -25,11 +25,10 @@ Even though fully homomorphic encryption (FHE) has become available in recent ti
|
|
|
25
25
|
|
|
26
26
|
- 🏎️ Notably faster
|
|
27
27
|
- 💻 Demands fewer computational resources
|
|
28
|
-
- 📏 Generating smaller ciphertexts
|
|
28
|
+
- 📏 Generating much smaller ciphertexts
|
|
29
|
+
- 🔑 Distributing much smaller keys
|
|
29
30
|
- 🧠 Well-suited for memory-constrained environments
|
|
30
31
|
- ⚖️ Strikes a favorable balance for practical use cases
|
|
31
|
-
- 🔑 Supporting encryption and decryption of vectors
|
|
32
|
-
- 🗝️ Performing homomorphic addition, homomorphic element-wise multiplication and scalar multiplication on encrypted vectors
|
|
33
32
|
|
|
34
33
|
# Installation [](https://pypi.org/project/lightphe/)
|
|
35
34
|
|
|
@@ -161,14 +160,14 @@ However, if you tried to multiply ciphertexts with RSA, or xor ciphertexts with
|
|
|
161
160
|
|
|
162
161
|
# Working with vectors
|
|
163
162
|
|
|
164
|
-
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support.
|
|
163
|
+
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support including homomorphic addition, element-wise multiplication and scalar multiplication.
|
|
165
164
|
|
|
166
165
|
```python
|
|
167
166
|
# build an additively homomorphic cryptosystem
|
|
168
167
|
cs = LightPHE(algorithm_name="Paillier")
|
|
169
168
|
|
|
170
169
|
# define plain tensors
|
|
171
|
-
t1 = [1.005, 2.05,
|
|
170
|
+
t1 = [1.005, 2.05, 3.5, 4]
|
|
172
171
|
t2 = [5, 6.2, 7.002, 8.02]
|
|
173
172
|
|
|
174
173
|
# encrypt tensors
|
|
@@ -178,13 +177,32 @@ c2 = cs.encrypt(t2)
|
|
|
178
177
|
# perform homomorphic addition
|
|
179
178
|
c3 = c1 + c2
|
|
180
179
|
|
|
180
|
+
# perform homomorphic element-wise multiplication
|
|
181
|
+
c4 = c1 * c2
|
|
182
|
+
|
|
183
|
+
# perform homomorphic scalar multiplication
|
|
184
|
+
k = 5
|
|
185
|
+
c5 = k * c1
|
|
186
|
+
|
|
181
187
|
# decrypt the addition tensor
|
|
182
188
|
t3 = cs.decrypt(c3)
|
|
183
189
|
|
|
184
|
-
|
|
185
|
-
|
|
190
|
+
# decrypt the element-wise multiplied tensor
|
|
191
|
+
t4 = cs.decrypt(c4)
|
|
192
|
+
|
|
193
|
+
# decrypt the scalar multiplied tensor
|
|
194
|
+
t5 = cs.decrypt(c5)
|
|
195
|
+
|
|
196
|
+
# data validations
|
|
197
|
+
threshold = 0.5
|
|
198
|
+
for i in range(0, len(t1)):
|
|
199
|
+
assert abs((t1[i] + t2[i]) - t3[i]) < threshold
|
|
200
|
+
assert abs((t1[i] * t2[i]) - t4[i]) < threshold
|
|
201
|
+
assert abs((t1[i] * k) - t5[i]) < threshold
|
|
186
202
|
```
|
|
187
203
|
|
|
204
|
+
Unfortunately, vector multiplication (dot product) requires both homomorphic addition and homomorphic multiplication and this cannot be done with partially homomorphic encryption algorithms.
|
|
205
|
+
|
|
188
206
|
# Contributing
|
|
189
207
|
|
|
190
208
|
All PRs are more than welcome! If you are planning to contribute a large patch, please create an issue first to get any upfront questions or design decisions out of the way first.
|
|
@@ -116,8 +116,8 @@ class LightPHE:
|
|
|
116
116
|
Returns
|
|
117
117
|
ciphertext (from lightphe.models.Ciphertext import Ciphertext): encrypted message
|
|
118
118
|
"""
|
|
119
|
-
if self.cs.keys.get("
|
|
120
|
-
raise ValueError("You must have
|
|
119
|
+
if self.cs.keys.get("public_key") is None:
|
|
120
|
+
raise ValueError("You must have public key to perform encryption")
|
|
121
121
|
|
|
122
122
|
if isinstance(plaintext, list):
|
|
123
123
|
# then encrypt tensors
|
|
@@ -141,6 +141,9 @@ class LightPHE:
|
|
|
141
141
|
if self.cs.keys.get("private_key") is None:
|
|
142
142
|
raise ValueError("You must have private key to perform decryption")
|
|
143
143
|
|
|
144
|
+
if self.cs.keys.get("public_key") is None:
|
|
145
|
+
raise ValueError("You must have public key to perform decryption")
|
|
146
|
+
|
|
144
147
|
if isinstance(ciphertext, EncryptedTensor):
|
|
145
148
|
# then this is encrypted tensor
|
|
146
149
|
return self.__decrypt_tensors(encrypted_tensor=ciphertext)
|
|
@@ -243,7 +246,9 @@ class LightPHE:
|
|
|
243
246
|
to publicly.
|
|
244
247
|
"""
|
|
245
248
|
keys = self.cs.keys
|
|
249
|
+
private_key = None
|
|
246
250
|
if public is True and keys.get("private_key") is not None:
|
|
251
|
+
private_key = keys["private_key"]
|
|
247
252
|
del keys["private_key"]
|
|
248
253
|
|
|
249
254
|
if public is False:
|
|
@@ -255,6 +260,10 @@ class LightPHE:
|
|
|
255
260
|
with open(target_file, "w", encoding="UTF-8") as file:
|
|
256
261
|
file.write(json.dumps(keys))
|
|
257
262
|
|
|
263
|
+
# restore private key if you dropped
|
|
264
|
+
if private_key is not None:
|
|
265
|
+
self.cs.keys["private_key"] = private_key
|
|
266
|
+
|
|
258
267
|
def restore_keys(self, target_file: str) -> dict:
|
|
259
268
|
"""
|
|
260
269
|
Restore keys from a file
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
# built-in dependencies
|
|
1
2
|
import random
|
|
2
|
-
import
|
|
3
|
+
import decimal
|
|
3
4
|
from typing import Optional
|
|
5
|
+
|
|
6
|
+
# 3rd party dependencies
|
|
4
7
|
import sympy
|
|
8
|
+
|
|
9
|
+
# project dependencies
|
|
5
10
|
from lightphe.models.Homomorphic import Homomorphic
|
|
6
11
|
from lightphe.commons.logger import Logger
|
|
7
12
|
|
|
@@ -45,7 +50,9 @@ class ElGamal(Homomorphic):
|
|
|
45
50
|
p = sympy.randprime(100, 2 ** int(key_size / 2) - 1)
|
|
46
51
|
|
|
47
52
|
# picking a generator g
|
|
48
|
-
g = random.randint(2, int(math.sqrt(p)))
|
|
53
|
+
# g = random.randint(2, int(math.sqrt(p))) # reaches int limit for 3072-bit key
|
|
54
|
+
# g = int(random.uniform(2, float(decimal.Decimal(p).sqrt())))
|
|
55
|
+
g = random.randint(2, int(decimal.Decimal(p).sqrt()))
|
|
49
56
|
|
|
50
57
|
# picking a private key x
|
|
51
58
|
x = random.randint(1, p - 2)
|
|
@@ -128,7 +128,12 @@ class GoldwasserMicali(Homomorphic):
|
|
|
128
128
|
xp = i % p
|
|
129
129
|
xq = i % q
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
# reaches int limit for 3072-bit key
|
|
132
|
+
# if pow(xp, int((p - 1) / 2), p) == 1 and pow(xq, int((q - 1) / 2), q) == 1:
|
|
133
|
+
if (
|
|
134
|
+
pow(xp, int((p - 1) // 2), p) == 1
|
|
135
|
+
and pow(xq, int((q - 1) // 2), q) == 1
|
|
136
|
+
):
|
|
132
137
|
m_binaries.append("0")
|
|
133
138
|
else:
|
|
134
139
|
m_binaries.append("1")
|
|
@@ -81,18 +81,21 @@ class OkamotoUchiyama(Homomorphic):
|
|
|
81
81
|
Returns:
|
|
82
82
|
ciphertext (int): encrypted message
|
|
83
83
|
"""
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
g = self.keys["public_key"]["g"]
|
|
86
86
|
n = self.keys["public_key"]["n"]
|
|
87
87
|
h = self.keys["public_key"]["h"]
|
|
88
88
|
r = random_key or self.generate_random_key()
|
|
89
89
|
|
|
90
|
-
if
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
# having private key is not a must to encrypt but still if you have
|
|
91
|
+
if self.keys.get("private_key") is not None:
|
|
92
|
+
p = self.keys["private_key"]["p"]
|
|
93
|
+
if plaintext > p:
|
|
94
|
+
plaintext = plaintext % p
|
|
95
|
+
logger.debug(
|
|
96
|
+
f"plaintext must be in scale [0, {p=}] but this is exceeded."
|
|
97
|
+
"New plaintext is {plaintext}"
|
|
98
|
+
)
|
|
96
99
|
return (pow(g, plaintext, n) * pow(h, r, n)) % n
|
|
97
100
|
|
|
98
101
|
def decrypt(self, ciphertext: int):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lightphe
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
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
|
|
@@ -19,7 +19,7 @@ License-File: LICENSE
|
|
|
19
19
|
<div align="center">
|
|
20
20
|
|
|
21
21
|
[](https://pepy.tech/project/lightphe)
|
|
22
|
-
[](https://github.com/serengil/LightPHE/stargazers)
|
|
22
|
+
[](https://github.com/serengil/LightPHE/stargazers)
|
|
23
23
|
[](https://github.com/serengil/LightPHE/actions/workflows/tests.yml)
|
|
24
24
|
[](https://github.com/serengil/LightPHE/blob/master/LICENSE)
|
|
25
25
|
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
@@ -41,11 +41,10 @@ Even though fully homomorphic encryption (FHE) has become available in recent ti
|
|
|
41
41
|
|
|
42
42
|
- 🏎️ Notably faster
|
|
43
43
|
- 💻 Demands fewer computational resources
|
|
44
|
-
- 📏 Generating smaller ciphertexts
|
|
44
|
+
- 📏 Generating much smaller ciphertexts
|
|
45
|
+
- 🔑 Distributing much smaller keys
|
|
45
46
|
- 🧠 Well-suited for memory-constrained environments
|
|
46
47
|
- ⚖️ Strikes a favorable balance for practical use cases
|
|
47
|
-
- 🔑 Supporting encryption and decryption of vectors
|
|
48
|
-
- 🗝️ Performing homomorphic addition, homomorphic element-wise multiplication and scalar multiplication on encrypted vectors
|
|
49
48
|
|
|
50
49
|
# Installation [](https://pypi.org/project/lightphe/)
|
|
51
50
|
|
|
@@ -177,14 +176,14 @@ However, if you tried to multiply ciphertexts with RSA, or xor ciphertexts with
|
|
|
177
176
|
|
|
178
177
|
# Working with vectors
|
|
179
178
|
|
|
180
|
-
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support.
|
|
179
|
+
You can encrypt the output vectors of machine learning models with LightPHE. These encrypted tensors come with homomorphic operation support including homomorphic addition, element-wise multiplication and scalar multiplication.
|
|
181
180
|
|
|
182
181
|
```python
|
|
183
182
|
# build an additively homomorphic cryptosystem
|
|
184
183
|
cs = LightPHE(algorithm_name="Paillier")
|
|
185
184
|
|
|
186
185
|
# define plain tensors
|
|
187
|
-
t1 = [1.005, 2.05,
|
|
186
|
+
t1 = [1.005, 2.05, 3.5, 4]
|
|
188
187
|
t2 = [5, 6.2, 7.002, 8.02]
|
|
189
188
|
|
|
190
189
|
# encrypt tensors
|
|
@@ -194,13 +193,32 @@ c2 = cs.encrypt(t2)
|
|
|
194
193
|
# perform homomorphic addition
|
|
195
194
|
c3 = c1 + c2
|
|
196
195
|
|
|
196
|
+
# perform homomorphic element-wise multiplication
|
|
197
|
+
c4 = c1 * c2
|
|
198
|
+
|
|
199
|
+
# perform homomorphic scalar multiplication
|
|
200
|
+
k = 5
|
|
201
|
+
c5 = k * c1
|
|
202
|
+
|
|
197
203
|
# decrypt the addition tensor
|
|
198
204
|
t3 = cs.decrypt(c3)
|
|
199
205
|
|
|
200
|
-
|
|
201
|
-
|
|
206
|
+
# decrypt the element-wise multiplied tensor
|
|
207
|
+
t4 = cs.decrypt(c4)
|
|
208
|
+
|
|
209
|
+
# decrypt the scalar multiplied tensor
|
|
210
|
+
t5 = cs.decrypt(c5)
|
|
211
|
+
|
|
212
|
+
# data validations
|
|
213
|
+
threshold = 0.5
|
|
214
|
+
for i in range(0, len(t1)):
|
|
215
|
+
assert abs((t1[i] + t2[i]) - t3[i]) < threshold
|
|
216
|
+
assert abs((t1[i] * t2[i]) - t4[i]) < threshold
|
|
217
|
+
assert abs((t1[i] * k) - t5[i]) < threshold
|
|
202
218
|
```
|
|
203
219
|
|
|
220
|
+
Unfortunately, vector multiplication (dot product) requires both homomorphic addition and homomorphic multiplication and this cannot be done with partially homomorphic encryption algorithms.
|
|
221
|
+
|
|
204
222
|
# Contributing
|
|
205
223
|
|
|
206
224
|
All PRs are more than welcome! If you are planning to contribute a large patch, please create an issue first to get any upfront questions or design decisions out of the way first.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
|
+
requirements.txt
|
|
3
4
|
setup.py
|
|
4
5
|
lightphe/__init__.py
|
|
5
6
|
lightphe.egg-info/PKG-INFO
|
|
@@ -34,6 +35,7 @@ tests/test_cloud.py
|
|
|
34
35
|
tests/test_damgard.py
|
|
35
36
|
tests/test_elgamal.py
|
|
36
37
|
tests/test_ellipticcurveelgamal.py
|
|
38
|
+
tests/test_exporting_keys.py
|
|
37
39
|
tests/test_goldwasser.py
|
|
38
40
|
tests/test_naccache.py
|
|
39
41
|
tests/test_okamoto.py
|
|
@@ -8,10 +8,11 @@ with open("requirements.txt", "r", encoding="utf-8") as f:
|
|
|
8
8
|
|
|
9
9
|
setuptools.setup(
|
|
10
10
|
name="lightphe",
|
|
11
|
-
version="0.0.
|
|
11
|
+
version="0.0.7",
|
|
12
12
|
author="Sefik Ilkin Serengil",
|
|
13
13
|
author_email="serengil@gmail.com",
|
|
14
14
|
description="A Lightweight Partially Homomorphic Encryption Library for Python",
|
|
15
|
+
data_files=[("", ["README.md", "requirements.txt"])],
|
|
15
16
|
long_description=long_description,
|
|
16
17
|
long_description_content_type="text/markdown",
|
|
17
18
|
url="https://github.com/serengil/LightPHE",
|
|
@@ -10,7 +10,10 @@ PUBLIC = {"public_key": {"n": 175501, "e": 101753}}
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def test_encryption():
|
|
13
|
-
|
|
13
|
+
# i actually have both private and public key
|
|
14
|
+
# but one can encrypt messages with public key only
|
|
15
|
+
cs = LightPHE(algorithm_name="RSA", keys=PUBLIC)
|
|
16
|
+
secret_cs = LightPHE(algorithm_name="RSA", keys=PRIVATE)
|
|
14
17
|
|
|
15
18
|
# plaintexts
|
|
16
19
|
m1 = 10000
|
|
@@ -19,15 +22,13 @@ def test_encryption():
|
|
|
19
22
|
m2 = 1.05
|
|
20
23
|
c2 = cs.encrypt(m2)
|
|
21
24
|
|
|
22
|
-
assert
|
|
23
|
-
|
|
25
|
+
assert secret_cs.decrypt(c1) == m1
|
|
24
26
|
logger.info("✅ Cloud encryption tests done")
|
|
25
27
|
|
|
26
28
|
c3_val = homomorphic_operations(c1=c1.value, c2=c2.value)
|
|
27
29
|
c3 = cs.create_ciphertext_obj(c3_val)
|
|
28
30
|
|
|
29
|
-
assert
|
|
30
|
-
|
|
31
|
+
assert secret_cs.decrypt(c3) == m1 * m2
|
|
31
32
|
logger.info("✅ Cloud decryption tests done")
|
|
32
33
|
|
|
33
34
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from lightphe import LightPHE
|
|
3
|
+
from lightphe.commons.logger import Logger
|
|
4
|
+
|
|
5
|
+
logger = Logger(module="tests/test_goldwasser.py")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# pylint: disable=eval-used
|
|
9
|
+
def test_private_available_after_export():
|
|
10
|
+
target_file = "my_public_key.lphe"
|
|
11
|
+
cs = LightPHE(algorithm_name="RSA")
|
|
12
|
+
# we are dropping private key while exporting public key
|
|
13
|
+
cs.export_keys(public=True, target_file=target_file)
|
|
14
|
+
assert cs.cs.keys.get("private_key") is not None
|
|
15
|
+
logger.info("✅ private key is not available in public key file as expected")
|
|
16
|
+
|
|
17
|
+
with open(target_file, "r", encoding="UTF-8") as file:
|
|
18
|
+
key_str = file.read()
|
|
19
|
+
keys = eval(key_str)
|
|
20
|
+
assert keys.get("private_key") is None
|
|
21
|
+
logger.info(
|
|
22
|
+
"✅ private key is available in cryptosystem's keys after"
|
|
23
|
+
"its public key exported as expected"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
os.remove(target_file)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|