lightphe 0.0.15__tar.gz → 0.0.17__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.15 → lightphe-0.0.17}/PKG-INFO +45 -212
- {lightphe-0.0.15 → lightphe-0.0.17}/README.md +44 -211
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/__init__.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/Benaloh.py +31 -19
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/DamgardJurik.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/ElGamal.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/EllipticCurveElGamal.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/GoldwasserMicali.py +36 -30
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/NaccacheStern.py +103 -94
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/OkamotoUchiyama.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/Paillier.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/models/Ciphertext.py +2 -2
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/models/Homomorphic.py +21 -7
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/models/Tensor.py +2 -2
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe.egg-info/PKG-INFO +45 -212
- lightphe-0.0.17/lightphe.egg-info/requires.txt +4 -0
- lightphe-0.0.17/requirements.txt +4 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/setup.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_benaloh.py +10 -3
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_damgard.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_elgamal.py +2 -2
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_ellipticcurveelgamal.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_goldwasser.py +10 -3
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_keys.py +7 -2
- lightphe-0.0.17/tests/test_naccache.py +203 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_okamoto.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_paillier.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_rsa.py +1 -1
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_salary.py +1 -1
- lightphe-0.0.15/lightphe.egg-info/requires.txt +0 -4
- lightphe-0.0.15/requirements.txt +0 -4
- lightphe-0.0.15/tests/test_naccache.py +0 -94
- {lightphe-0.0.15 → lightphe-0.0.17}/LICENSE +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/commons/__init__.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/commons/logger.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/commons/phe_utils.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/RSA.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/cryptosystems/__init__.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/models/Algorithm.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe/models/__init__.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe.egg-info/SOURCES.txt +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe.egg-info/dependency_links.txt +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/lightphe.egg-info/top_level.txt +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/setup.cfg +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/__init__.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_ciphertexts.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_cloud.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/tests/test_exporting_keys.py +0 -0
- {lightphe-0.0.15 → lightphe-0.0.17}/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.17
|
|
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
|
|
@@ -28,7 +28,7 @@ License-File: LICENSE
|
|
|
28
28
|
[](https://www.youtube.com/@sefiks?sub_confirmation=1)
|
|
29
29
|
[](https://twitter.com/intent/user?screen_name=serengil)
|
|
30
30
|
|
|
31
|
-
[](https://www.patreon.com/serengil?repo=lightphe)
|
|
32
32
|
[](https://github.com/sponsors/serengil)
|
|
33
33
|
[](https://buymeacoffee.com/serengil)
|
|
34
34
|
|
|
@@ -67,7 +67,7 @@ from lightphe import LightPHE
|
|
|
67
67
|
|
|
68
68
|
In summary, LightPHE is covering following algorithms and these are partially homomorphic with respect to the operations mentioned in the following table.
|
|
69
69
|
|
|
70
|
-
| Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Multiplication
|
|
70
|
+
| Algorithm | Multiplicatively<br>Homomorphic | Additively<br>Homomorphic | Scalar Multiplication | Exclusively<br>Homomorphic | Regeneration<br>of Ciphertext |
|
|
71
71
|
| --- | --- | --- | --- | --- | --- |
|
|
72
72
|
| RSA | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
73
73
|
| ElGamal | ✅ | ❌ | ❌ | ❌ | ✅ |
|
|
@@ -98,124 +98,56 @@ algorithms = [
|
|
|
98
98
|
"EllipticCurve-ElGamal"
|
|
99
99
|
]
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
cs = LightPHE(algorithm_name = algorithms[0])
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
#
|
|
104
|
+
# Homomorphic Operations
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
The following example demonstrates a simple workflow using LightPHE with an additively homomorphic cryptosystem (e.g. Paillier). First, we build the cryptosystem on-premises and define two plaintext values. Next, we encrypt the plaintexts, which can be done either on-premises or in the cloud, and does not require the private key. Homomorphic operations, such as addition and scalar multiplication, can then be performed on the ciphertexts—these operations can be offloaded to the cloud, leveraging its computational power without revealing the private key or the plaintext. Finally, the results are decrypted on-premises using the private key, verifying that the homomorphic operations on encrypted data produce the expected plaintext results.
|
|
107
107
|
|
|
108
108
|
```python
|
|
109
|
-
#
|
|
110
|
-
|
|
109
|
+
# build an additively homomorphic cryptosystem
|
|
110
|
+
cs = LightPHE(algorithm_name = "Paillier")
|
|
111
111
|
|
|
112
|
-
#
|
|
113
|
-
|
|
112
|
+
# define plaintexts
|
|
113
|
+
m1 = 10000 # base salary in usd
|
|
114
|
+
m2 = 500 # wage increase in usd
|
|
114
115
|
|
|
115
|
-
#
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# Homomorphic Operations
|
|
116
|
+
# encrypt plaintexts - private key is not required.
|
|
117
|
+
c1 = cs.encrypt(m1)
|
|
118
|
+
c2 = cs.encrypt(m2)
|
|
120
119
|
|
|
121
|
-
|
|
120
|
+
# homomorphic addition - private key is not required
|
|
121
|
+
c3 = c1 + c2
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```python
|
|
128
|
-
def on_premise() -> Tuple[int, int, dict]:
|
|
129
|
-
"""
|
|
130
|
-
Executes on-premise operations: initializes a cryptosystem by generating
|
|
131
|
-
a random public-private key pair, then encrypts two plaintext values.
|
|
132
|
-
|
|
133
|
-
Returns:
|
|
134
|
-
result (tuple): A tuple containing:
|
|
135
|
-
- c1 (int): The first ciphertext
|
|
136
|
-
- c2 (int): The second ciphertext
|
|
137
|
-
- public_key (dict): The public key for the cryptosystem
|
|
138
|
-
"""
|
|
139
|
-
# generate a random private-public key pair
|
|
140
|
-
phe = LightPHE(algorithm_name = "Paillier")
|
|
141
|
-
|
|
142
|
-
# define plaintexts
|
|
143
|
-
m1 = 10000 # base salary in usd
|
|
144
|
-
m2 = 500 # wage increase in usd
|
|
145
|
-
|
|
146
|
-
# calculate ciphertexts
|
|
147
|
-
c1 = phe.encrypt(m1).value
|
|
148
|
-
c2 = phe.encrypt(m2).value
|
|
149
|
-
|
|
150
|
-
return (c1, c2, phe.cs.public_key)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Homomorphic Operations on Cloud
|
|
154
|
-
|
|
155
|
-
This code snippet demonstrates how to perform homomorphic addition on the cloud side without using the private key. However, the cloud is unable to decrypt c3 itself, even though it is the one that calculated it.
|
|
123
|
+
# homomorphic scalar multiplication - private key is not required
|
|
124
|
+
k = 1.05 # increase something 5%
|
|
125
|
+
c4 = k * c1
|
|
156
126
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
Performs cloud-side operations: reconstructs a cryptosystem using the
|
|
161
|
-
provided public key and executes a homomorphic addition on two ciphertexts.
|
|
162
|
-
|
|
163
|
-
Args:
|
|
164
|
-
c1 (int): The first ciphertext
|
|
165
|
-
c2 (int): The second ciphertext
|
|
166
|
-
public_key (dict): The public key of an existing cryptosystem
|
|
167
|
-
Retunrs:
|
|
168
|
-
c3 (int): The resulting ciphertext after homomorphic addition
|
|
169
|
-
"""
|
|
170
|
-
# restore cryptosystem with just the public key
|
|
171
|
-
phe = LightPHE(algorithm_name = "Paillier", keys = public_key)
|
|
172
|
-
|
|
173
|
-
# cast c1 and c2 to ciphertext objects
|
|
174
|
-
c1 = phe.create_ciphertext_obj(c1)
|
|
175
|
-
c2 = phe.create_ciphertext_obj(c2)
|
|
176
|
-
|
|
177
|
-
# confirm that cloud cannot decrypt c1
|
|
178
|
-
with pytest.raises(ValueError, match="You must have private key"):
|
|
179
|
-
phe.decrypt(c1)
|
|
180
|
-
|
|
181
|
-
# confirm that cloud cannot decrypt c2
|
|
182
|
-
with pytest.raises(ValueError, match="You must have private key"):
|
|
183
|
-
phe.decrypt(c2)
|
|
184
|
-
|
|
185
|
-
# perform homomorphic addition
|
|
186
|
-
c3 = c1 + c2
|
|
187
|
-
|
|
188
|
-
# confirm that cloud cannot decrypt c3
|
|
189
|
-
with pytest.raises(ValueError, match="You must have private key"):
|
|
190
|
-
phe.decrypt(c3)
|
|
191
|
-
|
|
192
|
-
return c3.value
|
|
127
|
+
# decryption - private key is required
|
|
128
|
+
assert cs.decrypt(c3) == m1 + m2
|
|
129
|
+
assert cs.decrypt(c4) == k * m1
|
|
193
130
|
```
|
|
194
131
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
This code snippet demonstrates the proof of work. Even though c3 was calculated in the cloud by adding c1 and c2, on-premises can validate that its decryption must be equal to the addition of plaintexts m1 and m2.
|
|
132
|
+
On the other hand, if you adopt a multiplicatively homomorphic cryptosyste (e.g. RSA or ElGamal), you can multiply ciphertexts without revealing the private key or the plaintext.
|
|
198
133
|
|
|
199
134
|
```python
|
|
200
|
-
#
|
|
201
|
-
|
|
202
|
-
```
|
|
135
|
+
# build a multiplicatively homomorphic cryptosystem
|
|
136
|
+
cs = LightPHE(algorithm_name = "RSA")
|
|
203
137
|
|
|
204
|
-
|
|
138
|
+
# define plaintexts
|
|
139
|
+
m1 = 17
|
|
140
|
+
m2 = 21
|
|
205
141
|
|
|
206
|
-
|
|
142
|
+
# encrypt plaintexts - private key is not required.
|
|
143
|
+
c1 = cs.encrypt(m1)
|
|
144
|
+
c2 = cs.encrypt(m2)
|
|
207
145
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```python
|
|
211
|
-
# increasing something 5%
|
|
212
|
-
k = 1.05
|
|
213
|
-
|
|
214
|
-
# scalar multiplication - cloud (private key is not required)
|
|
215
|
-
c4 = k * c1
|
|
146
|
+
# homomorphic multiplication
|
|
147
|
+
c3 = c1 * c2
|
|
216
148
|
|
|
217
|
-
#
|
|
218
|
-
assert
|
|
149
|
+
# decryption - private key is required
|
|
150
|
+
assert cs.decrypt(c3) == m1 * m2
|
|
219
151
|
```
|
|
220
152
|
|
|
221
153
|
### Ciphertext Regeneration
|
|
@@ -223,28 +155,12 @@ assert phe.decrypt(c4) == k * m1
|
|
|
223
155
|
Similar to the most of additively homomorphic algorithms, Paillier lets you to regenerate ciphertext while you are not breaking its plaintext restoration. You may consider to do this re-generation many times to have stronger ciphertexts.
|
|
224
156
|
|
|
225
157
|
```python
|
|
226
|
-
c1_prime =
|
|
158
|
+
c1_prime = cs.regenerate_ciphertext(c1)
|
|
227
159
|
assert c1_prime.value != c1.value
|
|
228
|
-
assert
|
|
229
|
-
assert
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Unsupported Operations
|
|
233
|
-
|
|
234
|
-
Finally, if you try to perform an operation that algorithm does not support, then an exception will be thrown. For instance, Paillier is not homomorphic with respect to the multiplication or xor. To put it simply, you cannot multiply two ciphertexts. If you enforce this calculation, you will have an exception.
|
|
235
|
-
|
|
236
|
-
```python
|
|
237
|
-
# pailier is not multiplicatively homomorphic
|
|
238
|
-
with pytest.raises(ValueError, match="Paillier is not homomorphic with respect to the multiplication"):
|
|
239
|
-
c1 * c2
|
|
240
|
-
|
|
241
|
-
# pailier is not exclusively homomorphic
|
|
242
|
-
with pytest.raises(ValueError, match="Paillier is not homomorphic with respect to the exclusive or"):
|
|
243
|
-
c1 ^ c2
|
|
160
|
+
assert cs.decrypt(c1_prime) == m1
|
|
161
|
+
assert cs.decrypt(c1) == m1
|
|
244
162
|
```
|
|
245
163
|
|
|
246
|
-
However, if you tried to multiply ciphertexts with RSA, or xor ciphertexts with Goldwasser-Micali, these will be succeeded because those cryptosystems support those homomorphic operations.
|
|
247
|
-
|
|
248
164
|
### Elliptic Curve Cryptography
|
|
249
165
|
|
|
250
166
|
ECC is a powerful public-key cryptosystem based on the algebraic structure of elliptic curves over finite fields. The library supports 3 elliptic curve forms (weierstrass, edwards and koblitz) and 100+ standard elliptic curve configurations.
|
|
@@ -252,9 +168,10 @@ ECC is a powerful public-key cryptosystem based on the algebraic structure of el
|
|
|
252
168
|
In LightPHE, the [Elliptic Curve ElGamal](https://sefiks.com/2018/08/21/elliptic-curve-elgamal-encryption/) scheme is implemented, offering a secure and efficient homomorphic encryption option.
|
|
253
169
|
|
|
254
170
|
```python
|
|
171
|
+
forms = ["weierstrass", "edwards", "koblitz"]
|
|
255
172
|
phe = LightPHE(
|
|
256
173
|
algorithm_name="EllipticCurve-ElGamal",
|
|
257
|
-
form=
|
|
174
|
+
form=forms[1],
|
|
258
175
|
)
|
|
259
176
|
```
|
|
260
177
|
|
|
@@ -262,50 +179,11 @@ One of the crucial factors that define the security level of an elliptic curve c
|
|
|
262
179
|
|
|
263
180
|
Each curve in LightPHE has a specific order, which is carefully chosen to balance performance and security. By selecting an elliptic curve with a larger order, you increase the security of your cryptographic system, but this may come with a trade-off in computational efficiency. Therefore, choosing the appropriate curve order is a crucial decision based on your application’s security and performance requirements.
|
|
264
181
|
|
|
265
|
-
See [`curves`](https://github.com/serengil/LightECC) page for a list of all supported forms, curves and their details.
|
|
266
|
-
|
|
267
|
-
### Vector Embeddings and Tensors
|
|
268
|
-
|
|
269
|
-
LightPHE supports homomorphic encryption on vector embeddings and tensors. This is useful in privacy-preserving machine learning, secure aggregation, and confidential data processing.
|
|
270
|
-
|
|
271
|
-
```python
|
|
272
|
-
# build a cryptosystem
|
|
273
|
-
cs = LightPHE(algorithm_name="Paillier")
|
|
274
|
-
|
|
275
|
-
# define plain embedding
|
|
276
|
-
tensor = [1.005, 2.05, 3.005, 4.005, -5.05, 6, 7.003, 7.002]
|
|
277
|
-
|
|
278
|
-
# encrypt vector embedding
|
|
279
|
-
encrypted_tensors = cs.encrypt(tensor)
|
|
182
|
+
See [`curves`](https://github.com/serengil/LightECC#supported-curves) page for a list of all supported forms, curves and their details.
|
|
280
183
|
|
|
281
|
-
|
|
282
|
-
decrypted_tensors = cs.decrypt(encrypted_tensors)
|
|
184
|
+
### Vector Embeddings
|
|
283
185
|
|
|
284
|
-
|
|
285
|
-
assert all(abs(original - decrypted) < 1e-2 for original, decrypted in zip(tensor, decrypted_tensors))
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
Encrypted embeddings retain their homomorphic properties, enabling secure computations on encrypted data without decryption. For example, two embeddings encrypted using a multiplicatively homomorphic algorithm can be multiplied element-wise.
|
|
289
|
-
|
|
290
|
-
```python
|
|
291
|
-
# build a multiplicatively homomorphic cryptosystem (e.g. RSA)
|
|
292
|
-
cs = LightPHE("RSA")
|
|
293
|
-
|
|
294
|
-
# define plain embeddings
|
|
295
|
-
t1 = [1.005, 2.05, -3.5, 3.1, -4]
|
|
296
|
-
t2 = [5, 6.2, -7.002, -7.1, 8.02]
|
|
297
|
-
|
|
298
|
-
# encrypt embeddings
|
|
299
|
-
c1, c2 = cs.encrypt(t1), cs.encrypt(t2)
|
|
300
|
-
|
|
301
|
-
# perform element-wise homomorphic multiplication
|
|
302
|
-
c3 = c1 * c2
|
|
303
|
-
|
|
304
|
-
# proof of work
|
|
305
|
-
assert np.allclose(cs.decrypt(c3), [a * b for a, b in zip(t1, t2)], rtol=1e-2)
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
Similarly, two embeddings encrypted with an additively homomorphic algorithm can be added. Additionally, an encrypted embedding can be multiplied by a constant or a plain embedding.
|
|
186
|
+
LightPHE supports homomorphic encryption on vector embeddings. This is useful in privacy-preserving machine learning, secure aggregation, and confidential data processing.
|
|
309
187
|
|
|
310
188
|
```python
|
|
311
189
|
# build an additively homomorphic cryptosystem (e.g. Paillier)
|
|
@@ -334,51 +212,6 @@ assert np.allclose(cs.decrypt(c5), [a * 3 for a in t1], rtol=1e-2)
|
|
|
334
212
|
assert np.allclose(cs.decrypt(c6), [a * b for a, b in zip(t1, t3)], rtol=1e-2)
|
|
335
213
|
```
|
|
336
214
|
|
|
337
|
-
### Vector Similarity Search with PHE
|
|
338
|
-
|
|
339
|
-
Many machine learning models rely on a two-tower architecture, including facial recognition, reverse image search, recommendation engines, large language models, and more. In this setup, user and item inputs are separately mapped to vector embeddings.
|
|
340
|
-
|
|
341
|
-
For example, suppose all facial embeddings in your database are encrypted on-prem in advance. When verifying an identity, the attempted facial embedding is generated on an edge device or in the cloud. You can compute the encrypted similarity by performing a dot product between the encrypted vector and the plain vector, ensuring secure comparison without decrypting sensitive data. Only additively homomorphic cryptosystems offer encrypted similarity calculation.
|
|
342
|
-
|
|
343
|
-
```python
|
|
344
|
-
# define a plain vectors for source and target
|
|
345
|
-
alpha = [7.1, 5.2, 5.3, 2.4, 3.5, 4.6] # On-prem vector (user tower)
|
|
346
|
-
beta = [5.6, 3.7, 2.8, 4, 0, 5.9] # Cloud vector (item tower)
|
|
347
|
-
expected_similarity = sum(x * y for x, y in zip(alpha, beta))
|
|
348
|
-
|
|
349
|
-
# build an additively homomorphic cryptosystem (e.g. Paillier) on-prem
|
|
350
|
-
cs = LightPHE(algorithm_name = "Paillier", precision = 19)
|
|
351
|
-
|
|
352
|
-
# export keys
|
|
353
|
-
cs.export_keys("secret.txt")
|
|
354
|
-
cs.export_keys("public.txt", public=True)
|
|
355
|
-
|
|
356
|
-
# encrypt source embedding
|
|
357
|
-
encrypted_alpha = cs.encrypt(alpha)
|
|
358
|
-
|
|
359
|
-
# remove cryptosystem and plain alpha not to be leaked in cloud
|
|
360
|
-
del cs, alpha
|
|
361
|
-
|
|
362
|
-
# restore the cryptosystem in cloud with only public key
|
|
363
|
-
cloud_cs = LightPHE(algorithm_name = "Paillier", precision = 19, key_file = "public.txt")
|
|
364
|
-
|
|
365
|
-
# dot product of encrypted and plain embedding pair
|
|
366
|
-
encrypted_cosine_similarity = encrypted_alpha @ beta
|
|
367
|
-
|
|
368
|
-
# computed by the cloud but cloud cannot decrypt it
|
|
369
|
-
with pytest.raises(ValueError, match="must have private key"):
|
|
370
|
-
cloud_cs.decrypt(encrypted_cosine_similarity)
|
|
371
|
-
|
|
372
|
-
# restore the cryptosystem on-prem with secret key
|
|
373
|
-
cs = LightPHE(algorithm_name = "Paillier", precision = 19, key_file = "secret.txt")
|
|
374
|
-
|
|
375
|
-
# decrypt similarity (on prem)
|
|
376
|
-
calculated_similarity = cs.decrypt(encrypted_cosine_similarity)[0]
|
|
377
|
-
|
|
378
|
-
# proof of work
|
|
379
|
-
assert abs(calculated_similarity - expected_similarity) < 1e-2
|
|
380
|
-
```
|
|
381
|
-
|
|
382
215
|
# Contributing
|
|
383
216
|
|
|
384
217
|
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.
|
|
@@ -392,11 +225,11 @@ There are many ways to support a project - starring⭐️ the GitHub repo is jus
|
|
|
392
225
|
You can also support this work on [Patreon](https://www.patreon.com/serengil?repo=lightphe), [GitHub Sponsors](https://github.com/sponsors/serengil) or [Buy Me a Coffee](https://buymeacoffee.com/serengil).
|
|
393
226
|
|
|
394
227
|
<a href="https://www.patreon.com/serengil?repo=lightphe">
|
|
395
|
-
<img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/patreon.png" width="30%"
|
|
228
|
+
<img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/patreon.png" width="30%">
|
|
396
229
|
</a>
|
|
397
230
|
|
|
398
231
|
<a href="https://buymeacoffee.com/serengil">
|
|
399
|
-
<img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/bmc-button.png" width="25%"
|
|
232
|
+
<img src="https://raw.githubusercontent.com/serengil/LightPHE/master/icons/bmc-button.png" width="25%">
|
|
400
233
|
</a>
|
|
401
234
|
|
|
402
235
|
Also, your company's logo will be shown on README on GitHub if you become sponsor in gold, silver or bronze tiers.
|