lightphe 0.0.2__py3-none-any.whl → 0.0.3__py3-none-any.whl

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/__init__.py CHANGED
@@ -217,3 +217,14 @@ class LightPHE:
217
217
  else:
218
218
  raise ValueError(f"unimplemented algorithm - {algorithm_name}")
219
219
  return key_size
220
+
221
+ def create_ciphertext_obj(self, ciphertext: Union[int, tuple, list]) -> Ciphertext:
222
+ """
223
+ Ciphertext objects have keys in addition ciphertext itself to perform
224
+ homomorphic operations.
225
+ Args:
226
+ ciphertext (int or tuple or list): ciphertext content
227
+ Returns:
228
+ Ciphertext
229
+ """
230
+ return Ciphertext(algorithm_name=self.algorithm_name, keys=self.cs.keys, value=ciphertext)
@@ -49,7 +49,10 @@ class Ciphertext:
49
49
  self.cs: Homomorphic = cs
50
50
 
51
51
  def __str__(self) -> str:
52
- return str(self.value)
52
+ return f"Ciphertext({self.value})"
53
+
54
+ def __repr__(self) -> str:
55
+ return f"Ciphertext({self.value})"
53
56
 
54
57
  def __add__(self, other: "Ciphertext") -> "Ciphertext":
55
58
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightphe
3
- Version: 0.0.2
3
+ Version: 0.0.3
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
@@ -37,7 +37,15 @@ Requires-Dist: pytest (==7.1.2)
37
37
 
38
38
  LightPHE is a lightweight partially homomorphic encryption library for python. It is a hybrid homomoprhic encryption library wrapping many 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/), [`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/).
39
39
 
40
- Even though fully homomorphic encryption (FHE) has become available in recent times, but when considering the trade-offs, LightPHE emerges as a more efficient and practical choice. If your specific task doesn't demand the full homomorphic capabilities, opting for partial homomorphism with LightPHE is the logical decision. LightPHE is notably faster and demands fewer computational resources compared to FHE. Besides, it generates smaller ciphertexts, making it well-suited for memory-constrained environments. Finally, LightPHE strikes a favorable balance between security and efficiency for practical use cases.
40
+ # Partially vs Fully Homomorphic Encryption
41
+
42
+ Even though fully homomorphic encryption (FHE) has become available in recent times, but when considering the trade-offs, LightPHE emerges as a more efficient and practical choice. If your specific task doesn't demand the full homomorphic capabilities, opting for partial homomorphism with LightPHE is the logical decision.
43
+
44
+ - 🏎️ Notably faster
45
+ - 💻 Demands fewer computational resources
46
+ - 📏 Generating smaller ciphertexts
47
+ - 🧠 Well-suited for memory-constrained environments
48
+ - ⚖️ Strikes a favorable balance for practical use cases
41
49
 
42
50
  # Installation [![PyPI](https://img.shields.io/pypi/v/lightphe.svg)](https://pypi.org/project/lightphe/)
43
51
 
@@ -120,18 +128,30 @@ m2 = 23
120
128
  c1 = cs.encrypt(m1)
121
129
  c2 = cs.encrypt(m2)
122
130
 
123
- # performing homomorphic addition on ciphertexts
124
- assert cs.decrypt(c1 + c2) == m1 + m2
131
+ # homomorphic addition - private key is not required!
132
+ c3 = c1 + c2
133
+
134
+ # proof of work
135
+ assert cs.decrypt(c3) == m1 + m2
125
136
  ```
126
137
 
127
- Besides, Paillier is supporting multiplying ciphertexts by a known plain constant. Simply put, decryption of scalar multiplication of ciphertext is equivalent to that constant times plaintext as well.
138
+ ⚡ Notice that once can perform `c1 + c2` here without holding private key. However, just the data owner with private key can perform encryption and decryption. This is the basic definition of homomorphic encryption.
139
+
140
+ Besides, Paillier is supporting multiplying ciphertexts by a known plain constant. Simply put, decryption of scalar multiplication of ciphertext is equivalent to that constant times plaintext as well.
128
141
 
129
142
  ```python
130
- # scalar multiplication (increase its value 5%)
143
+ # increasing something 5%
131
144
  k = 1.05
132
- assert cs.decrypt(k * c1) == k * m1
145
+
146
+ # scalar multiplication - private key is not required!
147
+ c4 = k * c1
148
+
149
+ # proof of work
150
+ assert cs.decrypt(c4) == k * m1
133
151
  ```
134
152
 
153
+ ⚡ Herein, `k * c1` operation can be performed by anyone without holding private key.
154
+
135
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.
136
156
 
137
157
  ```python
@@ -144,11 +164,11 @@ assert cs.decrypt(c1) == m1
144
164
  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.
145
165
 
146
166
  ```python
147
- # pailier is not homomorphic with respect to the multiplication
167
+ # pailier is not multiplicatively homomorphic
148
168
  with pytest.raises(ValueError, match="Paillier is not homomorphic with respect to the multiplication"):
149
169
  c1 * c2
150
170
 
151
- # pailier is not homomorphic with respect to the xor
171
+ # pailier is not exclusively homomorphic
152
172
  with pytest.raises(ValueError, match="Paillier is not homomorphic with respect to the exclusive or"):
153
173
  c1 ^ c2
154
174
  ```
@@ -1,4 +1,4 @@
1
- lightphe/__init__.py,sha256=Q8b3_IWF9ZE8eNZLUw58JXCZE6UGoYSqwq6muXRb-LY,8452
1
+ lightphe/__init__.py,sha256=gi73bq3JA6KnIGYdtHB02awvfMw_4gpe0vDLDY-WXK4,8894
2
2
  lightphe/commons/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  lightphe/commons/logger.py,sha256=ci8TjKtNNSafe_G_E6L80WS-9nZfNhOerT1YRw3DnnM,1122
4
4
  lightphe/cryptosystems/Benaloh.py,sha256=L8x2fi9wAtiuGIDLn7iuo2uVYuhYYyKXjgzg2nPA8DY,7162
@@ -14,12 +14,13 @@ lightphe/cryptosystems/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
14
14
  lightphe/elliptic/Weierstrass.py,sha256=SutRA26XKRnJLgXl5qJVZyBo3okuKOkDW6v6SYd9xpE,3126
15
15
  lightphe/elliptic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  lightphe/models/Algorithm.py,sha256=VAWIWMqJ2IeV-JsV7kCEVKIBkjY8PlKzm-ByIsEZ5MA,402
17
- lightphe/models/Ciphertext.py,sha256=p309ER9c2-ekIL5-MOwc-BhxWx9kzN4WB2Zls7WhR9g,6152
17
+ lightphe/models/Ciphertext.py,sha256=LkDuFiBNZx5lGE_GhM1WEwZa3n72miY0XqHXt14gR-w,6239
18
18
  lightphe/models/EllipticCurve.py,sha256=XjlDlInAUxY3IsDJJRI9JACGz2JQyKzfcWFed80tSRI,468
19
19
  lightphe/models/Homomorphic.py,sha256=pkIK9Wd4an68mhnr-iRYHYQXFzibLMt5WW-er3-rOFM,1406
20
20
  lightphe/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  tests/__init__.py,sha256=Q8b3_IWF9ZE8eNZLUw58JXCZE6UGoYSqwq6muXRb-LY,8452
22
22
  tests/test_benaloh.py,sha256=yl0ZAak1WYE9OkFEAk44-yErXVTpJEFLOsMCSZJhkns,1516
23
+ tests/test_cloud.py,sha256=aykjgf0xGwIOrHvqrcZEnsRWtHMeByDhZHtklAyMi5I,1167
23
24
  tests/test_damgard.py,sha256=45tNxDG-22TTmSSA28e6lO_IQD8SiaraUZOG5BTQ0Ig,1544
24
25
  tests/test_elgamal.py,sha256=kOi121Pgii4iGaNm6urfiLudkzN6EkZHoHp9ZQXKMlY,3449
25
26
  tests/test_ellipticcurveelgamal.py,sha256=WwS6ke7T2CCZ_51UrqG0Eo0bjtFvegiM9WKjq6S-0ZM,1492
@@ -29,8 +30,8 @@ tests/test_okamoto.py,sha256=ysavBNz9E9bAd521PE4YWaragr3l0sNaGc0OMWhL5AM,1545
29
30
  tests/test_paillier.py,sha256=F56sLDX01begaSIbwBE-WDx62-2P8xgYv9dd9R531u0,2363
30
31
  tests/test_rsa.py,sha256=tzgknMUF0UNCJq3kapg0I6fB5Xk6_EupuDd9ttPc1hs,1285
31
32
  tests/test_salary.py,sha256=uFFMixNc5qxm_LG39gxGyqo8xfa1OEn7dmsHPUwoTns,1541
32
- lightphe-0.0.2.dist-info/LICENSE,sha256=Yaij6BkJXa3d0E7bxi0kAbI2JF7OH_tpe7HFiaJLBwY,1076
33
- lightphe-0.0.2.dist-info/METADATA,sha256=Wv3QFTskIUP1pZ1g4EPabc8bphDiksSy_GzBVZFLy-k,9888
34
- lightphe-0.0.2.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92
35
- lightphe-0.0.2.dist-info/top_level.txt,sha256=-xiT4F8yDH7SK2TyLnN7yxajFiaeyyQUYdsdDcXJf7s,15
36
- lightphe-0.0.2.dist-info/RECORD,,
33
+ lightphe-0.0.3.dist-info/LICENSE,sha256=Yaij6BkJXa3d0E7bxi0kAbI2JF7OH_tpe7HFiaJLBwY,1076
34
+ lightphe-0.0.3.dist-info/METADATA,sha256=0f6AC-7vpdfIf6pW2fTChDRu_WktasgnHha8VkG4oCM,10234
35
+ lightphe-0.0.3.dist-info/WHEEL,sha256=EVRjI69F5qVjm_YgqcTXPnTAv3BfSUr0WVAHuSP3Xoo,92
36
+ lightphe-0.0.3.dist-info/top_level.txt,sha256=-xiT4F8yDH7SK2TyLnN7yxajFiaeyyQUYdsdDcXJf7s,15
37
+ lightphe-0.0.3.dist-info/RECORD,,
tests/test_cloud.py ADDED
@@ -0,0 +1,44 @@
1
+ from lightphe.commons.logger import Logger
2
+ from lightphe import LightPHE
3
+
4
+ logger = Logger()
5
+
6
+ # pre-generated 20-bit RSA keys
7
+ PRIVATE = {"private_key": {"d": 30365}, "public_key": {"n": 175501, "e": 101753}}
8
+ PUBLIC = {"public_key": {"n": 175501, "e": 101753}}
9
+
10
+
11
+ def test_encryption():
12
+ cs = LightPHE(algorithm_name="RSA", keys=PRIVATE)
13
+
14
+ # plaintexts
15
+ m1 = 10000
16
+ c1 = cs.encrypt(m1)
17
+
18
+ # m2 = 1.05 # TODO: add support
19
+ m2 = 5
20
+ c2 = cs.encrypt(m2)
21
+
22
+ assert cs.decrypt(c1) == m1
23
+ assert cs.decrypt(c2) == m2
24
+
25
+ logger.info("✅ Cloud encryption tests done")
26
+
27
+ c3_val = homomorphic_operations(c1.value, c2.value)
28
+ c3 = cs.create_ciphertext_obj(c3_val)
29
+
30
+ assert cs.decrypt(c3) == m1 * m2
31
+
32
+ logger.info("✅ Cloud decryption tests done")
33
+
34
+
35
+ def homomorphic_operations(c1: int, c2: int):
36
+ """
37
+ One can perform homomorphic operations while he/she does not hold the private key
38
+ """
39
+ cs = LightPHE(algorithm_name="RSA", keys=PUBLIC)
40
+ c1_obj = cs.create_ciphertext_obj(c1)
41
+ c2_obj = cs.create_ciphertext_obj(c2)
42
+ c3 = c1_obj * c2_obj
43
+ logger.info("✅ Cloud homomorphic operation tests done")
44
+ return c3.value