Library Examples
The HEonGPU repository contains a rich set of sample programs designed to help users understand and experiment with the library’s functionalities. This guide provides a detailed walkthrough of each example, explaining its purpose and the key concepts demonstrated.
Basic Operations
These examples cover the fundamental workflows for the BFV, CKKS, and TFHE schemes.
1. Basic BFV Arithmetic (1_basic_bfv.cpp)
This example demonstrates the core workflow for performing exact integer arithmetic with the BFV scheme.
Workflow: It shows how to set up the
HEContextfor BFV, generate keys, encode a vector of integers into a plaintext, encrypt it, perform homomorphic multiplication and relinearization, and finally decrypt and decode the result.Key Concept: Noise Budget Management. The example explicitly prints the noise budget remaining in the ciphertext before and after operations using
decryptor.remainder_noise_budget().
2. Basic CKKS Arithmetic (2_basic_ckks.cpp)
This example introduces the CKKS scheme for approximate arithmetic on real numbers.
Workflow: It covers setting up the CKKS context, defining a
scalefor precision, encoding a vector of doubles, encrypting, performing homomorphic multiplication, and then applying the essentialrelinearizeandrescaleoperations.Key Concept: Scaling and Rescaling. It demonstrates the critical need to call
operators.rescale_inplace()after a multiplication to manage the scale of the ciphertext and control the precision of the approximate numbers.
3. Memory Pool Configuration (3_basic_memorypool_config.cpp)
This example shows how to configure HEonGPU’s memory pool sizes before generating a context.
Workflow: It sets host and device pool sizes using either percentage-based limits or explicit byte values, then generates the context with the custom configuration.
Key Concept: Memory pooling is initialized once and reused across contexts, so the first configuration controls pool sizing for the process.
4. BFV Logic Operations (9_basic_bfv_logic.cpp)
This example shows how to perform bitwise logic operations on encrypted binary data (0s and 1s) using the BFV scheme.
Workflow: It encrypts vectors of binary values and then uses the
HELogicOperatorclass to perform homomorphicANDandXNORoperations.Key Concept: The
HELogicOperatorprovides a dedicated interface for boolean computations, which are fundamental in many privacy-preserving applications.
5. CKKS Logic Operations (10_basic_ckks_logic.cpp)
Similar to the BFV logic example, this demonstrates performing logic gates on binary data that has been encoded within the CKKS scheme.
Workflow: It encrypts vectors of 0.0s and 1.0s and uses the
HELogicOperatorto performANDandXNORoperations.Key Concept: This showcases the versatility of the CKKS scheme, which can handle both approximate arithmetic and boolean logic.
6. Basic TFHE Operations (13_basic_tfhe.cpp)
This example provides a complete demonstration of the TFHE scheme for boolean circuit evaluation.
Workflow: It initializes a TFHE context, generates a secret key and a bootstrapping key, encrypts several boolean vectors, and then evaluates a series of logic gates (
NAND,AND,OR,XOR,NOT,MUX) on the ciphertexts.Key Concept: Gate Bootstrapping. Every binary gate operation (except for NOT) in TFHE involves a bootstrapping procedure to refresh the ciphertext, allowing for the evaluation of arbitrarily complex boolean circuits. This is demonstrated by passing the
boot_keyto each logic function.
Advanced Features
These examples demonstrate more advanced capabilities of the library, such as different key-switching methods and parallel execution with CUDA streams.
7. Key-Switching Methods in BFV (4_switchkey_methods_bfv.cpp)
This example explores the various key-switching operations available in the BFV scheme.
Workflow: After a standard multiplication and relinearization, it demonstrates how to perform
rotate_rowsandrotate_columnsusing Galois keys. It also shows how to perform akeyswitchoperation to change the secret key under which a ciphertext is encrypted.Key Concept: Galois Keys and Rotation. It illustrates how to generate
Galoiskeyobjects and use them to perform SIMD rotations on the encrypted vectors.
8. Key-Switching Methods in CKKS (5_switchkey_methods_ckks.cpp)
This example is the CKKS counterpart to the previous one, showcasing rotations and key-switching for approximate numbers.
Workflow: It demonstrates the use of
rotate_rows_inplacewith Galois keys and thekeyswitchoperation, highlighting that the core concepts are similar across both BFV and CKKS.Key Concept: Key-Switching Variants. The example is configured to use
KEYSWITCHING_METHOD_II, a more advanced hybrid method that can offer better performance than the defaultMETHOD_Iin certain scenarios.
9. Multi-Stream Parallel Execution (6_, 7_, 8_ examples)
This set of examples demonstrates how to leverage CUDA streams to execute multiple independent homomorphic operations concurrently, maximizing GPU utilization.
6_default_stream_usage.cpp: Serves as a baseline, performing a sequence of 64 operations serially in the default CUDA stream.
7_multi_stream_usage_way1.cpp: Uses OpenMP to parallelize a loop across multiple CPU threads. Each thread is assigned its own CUDA stream, and operations within that thread are submitted to its dedicated stream.
8_multi_stream_usage_way2.cpp: Shows an alternative approach where a single CPU thread manages multiple CUDA streams, assigning tasks to them in a round-robin fashion.Key Concept: By passing a
cudaStream_tobject viaExecutionOptions, users can direct HEonGPU to execute an operation on a specific stream, enabling powerful parallel execution patterns.
Serialization
10. Serialization in BFV and CKKS (11_, 12_ examples)
These examples demonstrate how to serialize and deserialize all major HEonGPU objects, which is essential for saving state, persistence, and client-server communication.
11_bfv_serialization.cppand12_ckks_serialization.cppshowcase the same workflow for their respective schemes.Workflow: They demonstrate serializing and deserializing every object type:
HEContext,Secretkey,Publickey,Relinkey,Galoiskey,Plaintext, andCiphertext.
- Key Concept: The library provides two main ways to serialize:
Directly calling
object.save(stream)andobject.load(stream)for raw, uncompressed binary data.Using the convenient
heongpu::serializerhelpers (e.g.,save_to_file,load_from_file), which automatically apply Zlib compression to reduce object size by 50-60%.
Bootstrapping Examples
These examples, located in the example/bootstrapping directory, demonstrate the use of the library’s powerful bootstrapping capabilities.
1_ckks_regular_bootstrapping.cpp: Shows how to refresh a CKKS ciphertext containing complex numbers.2_ckks_slim_bootstrapping.cpp: Demonstrates the more efficient slim bootstrapping variant for real numbers.3_ckks_bit_bootstrapping.cpp: Illustrates the specialized bootstrapping for binary data.4_ckks_gate_bootstrapping.cpp: Shows how to embed a logic gate within the bootstrapping process for maximum efficiency.
Multi-Party Computation Examples
These examples, located in the example/mpc directory, cover the library’s features for secure multi-party computation.
1_multiparty_computation_bfv.cppand2_multiparty_computation_ckks.cpp: Demonstrate the full protocol for N-out-of-N threshold FHE. This includes each party generating key shares, a server aggregating them into a single public key, encryption with the collective key, and finally, each party generating a partial decryption which are then combined to get the final result.3_mpc_collective_bootstrapping_bfv.cppand4_mpc_collective_bootstrapping_ckks.cpp: Showcase the advanced collective bootstrapping protocol, where multiple parties can jointly refresh a ciphertext without any single party having access to the full secret key.