In 1935, Boeing’s Model 299, the prototype of the B-17 Flying Fortress, crashed on its demonstration flight and killed the test pilot. The Army Air Corps called it ”too much airplane for one man to fly”. The fix wasn’t to dumb down the aircraft. A group of test pilots invented the pre-flight checklist, a step-by-step procedure that made an overwhelming machine manageable. The B-17 flew for decades, and the checklist became standard practice across all of aviation.
Fully homomorphic encryption (FHE) is the same kind of problem. Taken all at once, noise budgets, polynomial approximations, ciphertext packing, and parameter tradeoffs are too much to hold in your head. Taken one step at a time, building an FHE application is tractable. Here is the checklist.
First, what FHE actually is
Conventional encryption protects data at rest and in transit, but you have to decrypt data to compute on it, and that decryption is the exposure window where most breaches happen. FHE closes the window. It lets a server run computation directly on encrypted data and return an encrypted result, without ever seeing the plaintext or holding a decryption key. Only the data owner can read the answer.
That capability earns its overhead in specific situations: running sensitive workloads in cloud environments you don’t control, processing regulated data in healthcare and finance, and letting multiple parties compute over their combined data without any of them exposing their own. Federated learning and privacy-preserving ML inference are the fastest-moving examples. If your problem involves valuable data and an environment you can’t fully trust, FHE is worth a look.
One warning before the checklist: FHE protects data during computation but says nothing about what the result reveals. Where more than one party can decrypt, think hard about who holds keys and what the output discloses.
The checklist
- Start with the right architecture. Before you think about encryption, think about structure. FHE applications follow a natural client-server pattern: the client holds plaintext data, encrypts it, and sends the ciphertext to the server. The server performs computation on the encrypted data, then sends the encrypted result back. The client decrypts and reads the answer.
This means your program needs a clean separation. The server must be able to do its work without ever needing to peek at the data or ask the client for help mid-computation. No round trips, no branching based on intermediate values the server can’t see. Just one transmission in, one transmission out. If your application doesn’t fit this shape, you’ll need to rethink the design before going further.
In some cases—federated learning being a prominent example—there may be a multiple-client, single-server pattern to implement. FHE is amenable to this as well, but it introduces a question you need to think carefully about: which client or clients will be allowed to decrypt the program’s result? FHE protects data during computation, but it does not guarantee anything about what can be learned from the output of that computation. The cryptographic design of who holds decryption keys in such cases, and what the results reveal, requires significant thought beyond the mechanics of encryption itself.
2. Get it working in plaintext first. Write and test the whole program with no encryption. This version becomes your ground truth. You will restructure the code several times, and at each stage you need a reference to confirm nothing broke.
3. Remove data-dependent control flow. The server can’t inspect a value to choose a branch. Every if statement and every loop bound that depends on data has to go. Replace them with branchless computation: evaluate all paths and use an arithmetic selector to pick the result. Then test against your reference.
4. Understand multiplicative depth. This is the single most important concept in practical FHE. Every multiplication on encrypted data spends noise budget, a finite resource fixed at encryption time. Chain too many together and noise drowns the signal. The longest chain of dependent multiplications is your multiplicative depth, and it drives nearly every parameter choice you make. Reduce it where you can: favor addition over multiplication, use tree-structured reductions, and reorder operations to shorten the critical path. When depth exceeds the budget, a specialized operation called bootstrapping can be used to reset the noise so you can keep going. It needs no decryption but is very expensive and time-intensive, so avoid it where you can. In deep neural networks you often can’t.
5. Approximate your non-linear functions. Division, comparison, square root, sigmoid: none have direct FHE equivalents. Replace them with polynomial approximations, usually Chebyshev or Taylor series, or restructure to remove them. Each approximation adds multiplications and therefore depth, so accuracy trades directly against cost. Approximations are valid only over a bounded input range and diverge badly outside it, so normalize your inputs. Verify that accumulated error stays inside what your application can tolerate.
- Constrain data types and precision. FHE operates only on integers, because the hard math problems that make it secure are integer lattice problems. Move all data to integer or fixed-point, and aim for 32 bits of precision or less. Limiting the dynamic range of your inputs can save precision you would otherwise spend on outliers.
- Choose scheme, parameters, and packing together. These decisions are coupled. The BFV and BGV schemes handle exact integer arithmetic, common in image processing. CKKS is approximate and suits real-valued signal and medical data. Polynomial degree, typically 2^15 or 2^16, sets the multiplicative depth available, your memory footprint, and how many values you can pack into a single ciphertext. Use that packing. Modern schemes process tens of thousands of values in parallel at no extra cost, so you can pack the same feature across thousands of samples into one ciphertext. Finally the security parameter, how hard the encryption is to crack. This is a function of the other parameters you’ve chosen.128-bit security is the industry standard, and for most applications, is the practical ceiling.
- Pick a library. Actively maintained open-source options include OpenFHE (C++ with Python bindings) and Lattigo (Go). Libraries built on the TFHE scheme take a different path, so we haven’t addressed them here in this blog. OpenFHE is the safest default as it’s well supported and more battle-tested than the alternatives.
- Build, test, and debug. Swap each addition and multiplication for the library call, then generate keys. Alongside the secret and public keys, FHE needs evaluation keys that let the server compute but never decrypt. Relinearization keys are one example: after multiplying two ciphertexts the result is tangled with itself, and these untangle it without decrypting. Encrypt your test set, run, decrypt the result, and compare to the plaintext reference. Mismatches usually mean exhausted noise budget, too little precision, or a missed non-linear operation. To debug, use a local test environment to decrypt intermediate values one step at a time and compare to plaintext.
- Profile and iterate. Measure peak memory and wall-clock time. Gigabytes of memory and runtimes orders of magnitude slower than plaintext are normal. If that is unacceptable, loop back. Shave a level of depth, shrink parameters, pack more tightly, or cut precision. This is not a failure condition. It is the development cycle. The first working encrypted version is a milestone, not the finish line, and dedicated FHE hardware accelerators are starting to close the performance gap.
- Where to go from here. Once you’ve worked through a basic FHE application using one of the open-source libraries, the next challenge is improving the development workflow itself. Writing FHE applications still requires developers to reason about architecture, noise budgets, parameter selection, and client-server separation long before they write production code.
Whether you’re exploring FHE for the first time or looking to accelerate development of production workloads, open-source tools provide a practical place to start.
Your flying privacy fortress awaits. Aim high.


