LightPHE is a lightweight partially homomorphic encryption library for python. It is a hybrid homomoprhic encryption library wrapping many schemes such as RSA, ElGamal, Exponential ElGamal, Elliptic Curve ElGamal (Weierstrass, Koblitz and Edwards forms), Paillier, Damgard-Jurik, Okamoto–Uchiyama, Benaloh, Naccache–Stern, Goldwasser–Micali.
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.
- 🏎️ Notably faster
- 💻 Demands fewer computational resources
- 📏 Generating much smaller ciphertexts
- 🔑 Distributing much smaller keys
- 🧠 Well-suited for memory-constrained environments
- ⚖️ Strikes a favorable balance for practical use cases
The easiest way to install the LightPHE package is to install it from python package index (PyPI).
pip install lightpheThen you will be able to import the library and use its functionalities.
from lightphe import LightPHEIn summary, LightPHE is covering following algorithms and these are partially homomorphic with respect to the operations mentioned in the following table.
| Algorithm | Multiplicatively Homomorphic |
Additively Homomorphic |
Scalar Multiplication | Exclusively Homomorphic |
Regeneration of Ciphertext |
|---|---|---|---|---|---|
| RSA | ✅ | ❌ | ❌ | ❌ | ❌ |
| ElGamal | ✅ | ❌ | ❌ | ❌ | ✅ |
| Exponential ElGamal | ❌ | ✅ | ✅ | ❌ | ✅ |
| Elliptic Curve ElGamal | ❌ | ✅ | ✅ | ❌ | ❌ |
| Paillier | ❌ | ✅ | ✅ | ❌ | ✅ |
| Damgard-Jurik | ❌ | ✅ | ✅ | ❌ | ✅ |
| Benaloh | ❌ | ✅ | ✅ | ❌ | ✅ |
| Naccache-Stern | ❌ | ✅ | ✅ | ❌ | ✅ |
| Okamoto-Uchiyama | ❌ | ✅ | ✅ | ❌ | ✅ |
| Goldwasser-Micali | ❌ | ❌ | ❌ | ✅ | ❌ |
Once you imported the library, then you can build a cryptosystem for several algorithms. This basically generates private and public key pair.
algorithms = [
"RSA",
"ElGamal",
"Exponential-ElGamal",
"Paillier",
"Damgard-Jurik",
"Okamoto-Uchiyama",
"Benaloh",
"Naccache-Stern",
"Goldwasser-Micali",
"EllipticCurve-ElGamal"
]
cs = LightPHE(algorithm_name = algorithms[0])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.
# build an additively homomorphic cryptosystem
cs = LightPHE(algorithm_name = "Paillier")
# define plaintexts
m1 = 10000 # base salary in usd
m2 = 500 # wage increase in usd
# encrypt plaintexts - private key is not required.
c1 = cs.encrypt(m1)
c2 = cs.encrypt(m2)
# homomorphic addition - private key is not required
c3 = c1 + c2
# homomorphic scalar multiplication - private key is not required
k = 1.05 # increase something 5%
c4 = k * c1
# decryption - private key is required
assert cs.decrypt(c3) == m1 + m2
assert cs.decrypt(c4) == k * m1On the other hand, if you adopt a multiplicatively homomorphic cryptosystem (e.g. RSA or ElGamal), you can multiply ciphertexts without revealing the private key or the plaintext.
# build a multiplicatively homomorphic cryptosystem
cs = LightPHE(algorithm_name = "RSA")
# define plaintexts
m1 = 17
m2 = 21
# encrypt plaintexts - private key is not required.
c1 = cs.encrypt(m1)
c2 = cs.encrypt(m2)
# homomorphic multiplication
c3 = c1 * c2
# decryption - private key is required
assert cs.decrypt(c3) == m1 * m2The most of additively homomorphic algorithms allow 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.
c1_prime = cs.regenerate_ciphertext(c1)
assert c1_prime.value != c1.value
assert cs.decrypt(c1_prime) == m1
assert cs.decrypt(c1) == m1ECC 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 (default), edwards and koblitz) and 100+ standard elliptic curve configurations.
In LightPHE, the Elliptic Curve ElGamal scheme is implemented, offering a secure and efficient homomorphic encryption option.
forms = ["weierstrass", "edwards", "koblitz"]
phe = LightPHE(
algorithm_name="EllipticCurve-ElGamal",
form="edwards",
# curve="ed448", # optinally you can specify the curve for given form
)One of the crucial factors that define the security level of an elliptic curve cryptosystem is the order of the curve. The order of a curve is the number of points on the curve, and it directly influences the strength of the encryption. A higher order typically corresponds to a stronger cryptosystem, making it more resistant to cryptographic attacks.
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.
See curves page for a list of all supported forms, curves and their details.
LightPHE supports homomorphic encryption on vector embeddings. This is useful in privacy-preserving machine learning, secure aggregation, and confidential data processing.
# build an additively homomorphic cryptosystem (e.g. Paillier)
cs = LightPHE("Paillier")
# define plain embeddings
t1 = [1.005, 2.05, 3.6, 4, 4.02, 3.5]
t2 = [5, 6.2, 7.5, 8.02, 8.02, 4.5]
t3 = [1.03, 2.04, 3.05, 7.02, 2.01, 1.06]
# encrypt embeddings
c1, c2 = cs.encrypt(t1), cs.encrypt(t2)
# perform addition of two encrypted embeddings
c4 = c1 + c2
# perform scalar multiplication on an embedding
c5 = 3 * c1
# perform element-wise multiplication between an encrypted embedding and plain embedding
c6 = c1 * t3
# encrypted dot product (likewise cosine similarity)
c7 = c1 @ t3
# proof of work
assert np.allclose(cs.decrypt(c4), [a + b for a, b in zip(t1, t2)], rtol=1e-2)
assert np.allclose(cs.decrypt(c5), [a * 3 for a in t1], rtol=1e-2)
assert np.allclose(cs.decrypt(c6), [a * b for a, b in zip(t1, t3)], rtol=1e-2)
assert np.allclose(cs.decrypt(c7)[0], sum([a * b for a, b in zip(t1, t3)]), rtol=1e-2)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.
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 before approval.
There are many ways to support a project - starring⭐️ the GitHub repo is just one 🙏
You can also support this work on Patreon, GitHub Sponsors or Buy Me a Coffee.
Also, your company's logo will be shown on README on GitHub if you become sponsor in gold, silver or bronze tiers.
Please cite LightPHE in your publications if it helps your research. Here is its BibTex entry:
@article{serengil2024lightphe,
title={LightPHE: Integrating Partially Homomorphic Encryption into Python with Extensive Cloud Environment Evaluations},
author={Serengil, Sefik Ilkin and Ozpinar, Alper},
journal={arXiv preprint arXiv:2408.05219},
note={doi: 10.48550/arXiv.2408.05219. [Online]. Available: \url{https://arxiv.org/abs/2408.05219}},
year={2025}
}@article{serengil2025vectorsimilarity,
title={Encrypted Vector Similarity Computations Using Partially Homomorphic Encryption: Applications and Performance Analysis},
author={Serengil, Sefik and Ozpinar, Alper},
journal={arXiv preprint arXiv:2503.05850},
note={doi: 10.48550/arXiv.2503.05850. [Online]. Available: \url{https://arxiv.org/abs/2503.05850}},
year={2025}
}Also, if you use LightPHE in your projects, please add lightphe in the requirements.txt.
LightPHE is licensed under the MIT License - see LICENSE for more details.