Why I Ported Partially Homomorphic Encryption Library to Go

Homomorphic Encryption is a powerful cryptographic primitive. It allows us to perform computations on encrypted data without ever decrypting it. A while ago, I created LightPHE – a lightweight partially homomorphic encryption – in Python to provide a unified, accessible library supporting a wide range of PHE schemes—from classic RSA and Paillier to ElGamal, Elliptic Curve variants. While Python was the ideal language for rapid prototyping, accessibility, and research, bringing homomorphic encryption to real-world applications quickly revealed a critical trade-off. Here is why I decided to rewrite LightPHE in Go, and what lightphe-go brings to the table.

Mascot of the lightphe-go

The Python Dilemma: Usability vs. Execution Speed

Python is unmatched when it comes to API design, readability, and educational value. Developing LightPHE in Python allowed me to implement over a dozen schemes with clean, elegant syntax.


🙋‍♂️ You may consider to enroll my top-rated cryptography course on Udemy

Public Key Cryptography From Scratch

However, homomorphic encryption is inherently heavy on mathematics:

  • Large-integer modular exponentiations
  • Point additions and scalar multiplications over Elliptic Curves
  • Frequent cryptographic transformations across large datasets

In Python, executing these CPU-bound mathematical operations over large vectors introduces noticeable overhead. While Python excels as an interface layer or a research sandbox, production environments—especially cloud microservices and privacy-preserving backends—demand strict latency and concurrency guarantees.

Why Go?

To scale LightPHE for production-grade workloads, Go stood out for three key reasons:

  1. Near-Native Performance without C/C++ Complexity C and C++ are traditional choices for cryptography, but they come with memory management overhead and complex build systems. Go delivers near-native execution speed with strong type safety, automatic memory management, and a clean standard library.
  2. First-Class Concurrency (Goroutines) PHE operations are embarrassingly parallelizable. Encrypting a batch of numbers or performing homomorphic additions across a dataset can be easily split across CPU cores. Go’s built-in concurrency model (goroutines) makes parallelizing homomorphic operations trivial and highly efficient.
  3. Backend & Cloud Ecosystem Alignment Modern privacy-preserving systems are built into cloud-native environments, microservices, and API gateways. Go is the language of Kubernetes, Docker, and modern backend infrastructure, making lightphe-go infinitely easier to integrate into real-world pipelines.

Alignment with Privacy-Preserving Blockchain & Cloud Ecosystems

Go is the de facto language of modern decentralized platforms, cloud infrastructure, and distributed systems:

  • Blockchain & Web3: Infrastructure giants like Ethereum (Geth), Cosmos SDK, and Hyperledger Fabric are built natively in Go. As smart contracts and decentralized networks move toward Zero-Knowledge proofs and Privacy-Preserving Computation, integrating a lightweight Homomorphic Encryption library directly in Go eliminates cross-language bindings and foreign-function overhead.
  • Confidential Computing & Microservices: Modern cloud-native backends (powered by Docker and Kubernetes, both Go-based) increasingly handle sensitive financial, medical, and personal data. lightphe-go allows these microservices to perform encrypted data aggregation, secure voting, or privacy-preserving telemetry directly within their native Go pipelines.

What Changes in lightphe-go?

  • Identical Cryptographic Support: lightphe-go retains support for the same wide variety of algorithms (Paillier, ElGamal, Damgard-Jurik, Goldwasser-Micali, and more).
  • Blazing Fast Operations: Native big-integer math and optimized data structures drastically reduce encryption, decryption, and evaluation latency.
  • Zero Dependency Bloat: Built with Go’s robust standard crypto packages and clean architecture.

Code Wins Arguments

lightphe-go is a pure Go port that brings all cryptosystems (and embedded elliptic curve arithmetic from LightECC) into a single, clean API.

Quickstart: Installation & Import

Getting started with lightphe-go requires zero complex setup or external C-bindings. You only need Go 1.17+:

go get github.com/serengil/lightphe-go

Then, import it into your Go project:

import "github.com/serengil/lightphe-go/lightphe"

Developer-Friendly Design: You don’t need to import multiple sub-packages. That single import re-exports all essential algorithm constants, error sentinels, and ciphertext types. You can immediately call lightphe.Paillier, lightphe.Ciphertext, or handle errors like lightphe.ErrUnsupportedOperation directly.

1. Zero-Trust Cloud Offloading (Split Trust)

The primary use case for PHE is generating keys on-premises, handing only the public key to a cloud evaluator, and decrypting the result back home:

// On premises: Generate key pair and export ONLY public key to cloud
cs, _ := lightphe.New(lightphe.Paillier)
_ = cs.ExportKeys("public.json", true)   // public key only
_ = cs.ExportKeys("private.json", false) // private key stays safe

// On the untrusted cloud evaluator:
cloud, _ := lightphe.New(lightphe.Paillier, lightphe.WithKeyFile("public.json"))
c1, _ := cloud.EncryptInt(10000)
c2, _ := cloud.EncryptInt(500)

// Homomorphic addition on encrypted data
result, _ := c1.Add(c2)

// The cloud cannot decrypt what it just computed:
_, err := cloud.Decrypt(result)
if !errors.Is(err, lightphe.ErrMissingPrivateKey) {
    panic("expected ErrMissingPrivateKey")
}

// Back on premises: Decrypt the final result
onprem, _ := lightphe.New(lightphe.Paillier, lightphe.WithKeyFile("private.json"))
m, _ := onprem.Decrypt(result) // Returns 10500

2. Homomorphic Operations & Scalar Multiplications

You can compute salary additions or wage increases directly on ciphertexts:

const (
    m1 = 10000 // base salary
    m2 = 500   // bonus
    k  = 1.05  // 5% wage increase
)

cs, _ := lightphe.New(lightphe.Paillier)

salary, _ := cs.EncryptInt(m1)
raise, _ := cs.EncryptInt(m2)

// Homomorphic addition: E(m1) + E(m2) -> E(m1 + m2)
total, _ := salary.Add(raise)

// Scalar multiplication: E(m1) * k -> E(m1 * k)
increased, _ := salary.MultiplyByFloat(k)

sum, _ := cs.Decrypt(total)         // 10500
scaled, _ := cs.Decrypt(increased)  // 10500

3. Privacy-Preserving Vector Embeddings & Similarity Search

For privacy-preserving AI and database search, lightphe-go supports encrypted tensors, computing element-wise operations and dot products concurrently:

cs, _ := lightphe.New(lightphe.Paillier)

t1 := []float64{1.005, 2.05, 3.6, 4.0, 4.02, 3.5}
t2 := []float64{1.03, 2.04, 3.05, 7.02, 2.01, 1.06}

c1, _ := cs.EncryptTensor(t1)

// Encrypted dot product (e.g., for secure cosine similarity)
similarity, _ := c1.Dot(t2)

Supporting 12+ Cryptosystems Out of the Box

lightphe-go supports a comprehensive suite of partially and somewhat homomorphic encryption schemes:





AlgorithmMultiplicativeAdditiveScalar Mult.Bitwise-XORBitwise-AND
RSA
ElGamal
Exponential ElGamal
Elliptic Curve ElGamal
Paillier
Damgard-Jurik
Okamoto–Uchiyama
Benaloh
Naccache–Stern
Goldwasser-Micali
Sander-Young-Yung
Boneh-Goh-Nissim1️⃣

Python for Research and Prototyping, Go for Production

This isn’t the end of Python’s LightPHE, and this project isn’t about replacing Python.

Python remains the best entry point for researchers, students, and developers building Proof-of-Concepts (PoC) or testing new privacy-preserving pipelines. LightPHE (Python) will continue to serve as the research-first library.

LightPHE-Go, on the other hand, is built for scale, performance, and seamless backend integration.

Check out the repository, run the benchmarks, and let me know what you think!

There are many ways to support an open source project, and starring its GitHub repo is just a one!


Support this blog financially if you do like!

Buy me a coffee      Buy me a coffee


Leave a Reply