Homomorphic Encryption on IBM i, We successfully validated the execution of it on the IBM i Power Systems architecture. By utilizing the PASE (Portable Application Solutions Environment) and Python 3.9, I transitioned from basic encryption tests to a comprehensive “Secure Payroll” simulation.
Table of Contents
Initially, I attempted to install TenSEAL on IBM, but I encountered an error.
While true Fully Homomorphic Encryption (FHE) remains a challenge for this environment, Partially Homomorphic Encryption (PHE) proved to be a high-performance, viable solution for secure data processing.
1. The Core Constraint: Why FHE vs. PHE?
During the initial phase, I identified a critical technical distinction.
The Limitation: True Fully Homomorphic Encryption (FHE) (e.g., TFHE, CKKS) allows for infinite combinations of addition and multiplication. However, FHE libraries typically require massive C++ backends (like Microsoft SEAL) that are difficult to compile within the IBM i PASE environment due to specific dependency requirements. (If you know of a way to do this, please comment and let me know.)
The Solution: We pivoted to Partially Homomorphic Encryption (PHE). PHE allows one type of operation (either addition or multiplication) on encrypted data. For 90% of business use cases—like summing financial columns or counting records—PHE is more than sufficient and significantly faster than FHE.
2. Tools of the Trade: phe vs. lightphe
We tested two primary Python libraries to facilitate our POC:
Library
Focus
Why we used it
phe
Specialized
Implements the Paillier cryptosystem. It is “no-frills” and mathematically transparent.
lightphe
Versatile
An abstraction layer supporting 10+ algorithms (RSA, ElGamal, ECC, etc.). It allowed us to swap algorithms with one line of code.
3. The Testing: Step-by-Step
TEST Environment IBM i LPAR Resource Allocation
SYSTEM TYPE-MODEL: 9009-41G.
PROCESSOR FEATURE CODE: EP50.
PROCESSOR GROUP: P05.
ENTITLED PROCESSING CAPACITY: 1.00.
MEMORY: 64GB
The Python scripts related to this Proof of Concept can be found in the following Git repository.
We started by verifying that the IBM i could handle the large-integer math required for encryption. Using the phe library, we performed “Blind Addition”:
Encrypt
Encrypt
Perform (while both remain encrypted)
Decrypt
Perform
Decrypt
[STEP 1] Generating Keypair…
Action: System is accessing /dev/urandom to find two large primes (p and q).
Result: Public Key ‘n’ generated. Length: 308 digits.
Time Taken: 0.0965 seconds.
[STEP 2] Encrypting Plaintext: 50
Action: Computing c = (g^m * r^n) mod n^2.
Result (Truncated): 63581599557895054888091402643103470260622750787582…02486840304751070954627924474190222168162975323102
Observation: The number ’50’ is now a 616 character integer.
Time Taken: 0.0264 seconds.
[STEP 3] Encrypting Plaintext: 75
Action: Computing c = (g^m * r^n) mod n^2.
Result (Truncated): 396484062077405819610390207902881541911784537724789629233492081372235563372…330357816450241627192833522774791530318688276461849762267547329895209333662
Observation: The number ’75’ is now a 616 character integer.
Action: Multiplying the two ciphertexts together modulo n^2.
— WHY MULTIPLY? —
In the Paillier cryptosystem, the product of two ciphertexts corresponds to the sum of their underlying plaintexts.
Mathematically: Decrypt(C1 * C2) = (M1 + M2).
Note: The CPU never sees the values 50 or 75 during this step!
Result (Truncated) New ciphertext generated.: 50296166097283840986610944185335739574872806234147139942352768369890655436380031612630481366168055848427549331161930026649187…50813455025661672874672581017407344599483640405001993728662424772619537630834395096798036008592623042643885819573503178081224
Observation: The number ‘125’ is now a 617 character integer.
Action: Raising the ciphertext of the sum to the power of 4.
Result: Final encrypted result ready for decryption.
Time Taken: 0.0001 seconds.
[STEP 6] Decrypting Final Result…
Action: Using private key (factors p and q) to reverse the modular exponentiation.
Final Decrypted Value: 500
Mathematical Verification: (50 + 75) * 4 = 500
Decryption Time: 0.0075 seconds.
Phase 2: Basic Math Validation with lightphe
Phase 3: Performance Benchmarking
We ran a comprehensive benchmark across all supported lightphe types to find the “Champion” algorithm for the Power9 processor.
The Benchmark Script Logic:
The script measured Key Generation, Encryption, Math Operations, and Decryption for 10 different algorithms, including RSA, Paillier, and Elliptic Curve ElGamal.
The Results (Actual IBM i Data):
Speed Champion:Exponential-ElGamal (Add) was the fastest for encryption (0.0023s).
Storage Winner:EllipticCurve-ElGamal produced the smallest ciphertexts.
Anomaly:Benaloh took over 600 seconds for Key Generation, proving it’s unsuitable for this architecture.
Phase 3: Real-World Payroll Simulation
We simulated a secure payroll process: encrypting 8 salaries, summing them homomorphically, and saving the result to the Integrated File System (IFS).
The result just saws one of the most important lessons in a Cryptography POC: The Precision Gap.
The result returned 54901, but the expected math was 54900. This “off-by-one” error isn’t a bug in IBM i or in my Python code; it is a side effect of how Exponential ElGamal handles negative numbers and floating-point logic in some library implementations.
The “Hidden” Floating Point Issue
The Negative Number “Mapping”
Discrete Logarithm “Approximation”
To get 100% precision on IBM i, we must stick strictly to Integer Math.
The Fix: Instead of thinking in “Tax Rates” (1.10), think in “Cents” or “Basis Points.”
4. Key Observations & Findings
The “Discrete Log” Bottleneck
A major discovery during the Exponential-ElGamal test was the Decryption Gap:
Encryption Time: 0.0199s
Decryption Time: 1.3680s
Reason: Additive ElGamal requires the system to “search” for the plaintext answer (the Discrete Logarithm Problem). While encryption is instant, decryption takes longer as the total value increases.
Data Persistence
We confirmed that ciphertexts are not just temporary memory objects. By using Python’s pickle module, we successfully converted encrypted objects into binary blobs and stored them in /home/user/payroll_vault.dat. These files can be read back by a separate job later, mimicking a real-world batch processing cycle.
payroll_vault.dat (encrypted data)
payroll_vault.dat (hex value)
In this script, the cs object contains both the public and private keys. In a real production environment on IBM i:
The Public Key would be stored on the partition that encrypts.
The Private Key would be stored on a highly restricted partition or a secure “Vault” job that only runs when a CFO authorizes a decryption.
5. Limitations & Constraints
Memory Footprint: Ciphertexts are significantly larger than plaintexts. A 4-byte integer can become a 512-byte encrypted blob.
Dependency Management: Libraries like pandas are difficult to install on IBM i Python 3.9 due to C-extension requirements. We successfully bypassed this using the tabulate library for reporting.
CPU Spikes: Intensive modular exponentiation will cause momentary CPU spikes on the partition.
6. Final Outcome
We proved that an IBM i developer can secure sensitive data columns using PHE with minimal latency for math operations. By choosing Exponential-ElGamal for speed or Paillier for mathematical reliability, organizations can perform analytics on sensitive data without ever “opening” the envelope containing the actual values.
7. What’s Next?
To take this from POC to advanced concepts, the next steps may include:
Db2 Integration: Wrapping these Python scripts into an external stored procedure to be called directly via SQL.
Key Management: Moving keys from Python scripts into a secure IBM i Validation List (*VLDL) or a hardware security module.
Advanced Calculations: Perform advanced calculations in ElGamal, To do “Advanced” math, we can use a combination of Homomorphic Operations and Plaintext Constants.