Getting Started
This section provides a practical guide to installing the HEonGPU library, verifying the installation by running tests and examples, and executing your first encrypted computation. The process is designed to be straightforward for developers familiar with C++ and CMake in a Linux environment.
Prerequisites
Before building the library, ensure your development environment meets the following requirements. The library handles most of its third-party C++ dependencies (like GPU-NTT, RMM, Thrust, and GoogleTest) automatically via CMake.
System Dependencies:
CMake: Version 3.26.4 or higher
GCC: A modern C++ compiler with C++17 support
GMP: The GNU Multiple Precision Arithmetic Library
CUDA Toolkit: Version 11.4 or higher
OpenSSL: Version 1.1.0 or higher
ZLIB: The data compression library
Building the Library
The library uses a standard CMake build process. The most critical configuration step is specifying the correct compute capability for your target GPU, as this is essential for both correctness and performance.
- Step 1: Clone the Repository
First, obtain the source code from the official GitHub repository.
git clone https://github.com/Alisah-Ozcan/HEonGPU.git cd HEonGPU
- Step 2: Configure with CMake
Run CMake from the root of the repository to generate the build files. You must set the
CMAKE_CUDA_ARCHITECTURESvariable to match your GPU’s architecture. This flag instructs the CUDA compiler (nvcc) to generate code specifically optimized for your hardware.cmake -S . -D CMAKE_CUDA_ARCHITECTURES=XX -B build
Replace
XXwith the appropriate value from the table below. For example, for an NVIDIA RTX 4090 (Ada Lovelace architecture), you would use89.GPU Architecture to CMAKE_CUDA_ARCHITECTURES Mapping GPU Architecture
Compute Capability
Volta
70, 72
Turing
75
Ampere
80, 86
Ada Lovelace
89, 90
- Step 3: Compile the Library
Once configuration is complete, build the library using the following command. The
-jNflag will use multiple cores to speed up compilation. ReplaceNby the number of your logical cores (i.e. the output ofnproc).cmake --build ./build/ -jN
- Step 4: Install (Optional)
To install the library system-wide (e.g., in /usr/local/lib and /usr/local/include), run the install command.
sudo cmake --install build
Verifying the Installation
After a successful build, you can verify the library’s functionality by running the built-in tests, benchmarks, and examples. To do this, you must enable them during the CMake configuration step.
- To build and run tests:
# Configure with tests enabled cmake -S . -D HEonGPU_BUILD_TESTS=ON -D CMAKE_CUDA_ARCHITECTURES=89 -B build # Build cmake --build ./build/ -j # Run all tests cmake --build build --target test
- To build and run examples:
# Configure with examples enabled cmake -S . -D HEonGPU_BUILD_EXAMPLES=ON -D CMAKE_CUDA_ARCHITECTURES=89 -B build # Build cmake --build ./build/ -j # Run a specific example ./build/bin/examples/1_basic_bfv
Your First Encrypted Computation
The following “toy example” from the repository demonstrates a complete FHE workflow: setting up the context, generating keys, encoding, encrypting, performing a homomorphic addition, decrypting, and decoding the result.
1 #include "heongpu.cuh"
2
3 int main() {
4 // 1. Set up the HEContext for the BFV scheme
5 heongpu::HEContext<heongpu::Scheme::BFV> context(
6 heongpu::keyswitching_type::KEYSWITCHING_METHOD_I);
7
8 // 2. Define and set encryption parameters
9 size_t poly_modulus_degree = 8192;
10 context.set_poly_modulus_degree(poly_modulus_degree);
11 context.set_coeff_modulus_default_values(1); // Use 1 default prime for the coeff modulus
12 int plain_modulus = 1032193;
13 context.set_plain_modulus(plain_modulus);
14 context.generate(); // Finalize context and pre-compute values on GPU
15
16 // 3. Generate keys
17 heongpu::HEKeyGenerator<heongpu::Scheme::BFV> keygen(context);
18 heongpu::Secretkey<heongpu::Scheme::BFV> secret_key(context);
19 keygen.generate_secret_key(secret_key);
20
21 heongpu::Publickey<heongpu::Scheme::BFV> public_key(context);
22 keygen.generate_public_key(public_key, secret_key);
23
24 // 4. Create Encoder, Encryptor, Decryptor, and Operator objects
25 heongpu::HEEncoder<heongpu::Scheme::BFV> encoder(context);
26 heongpu::HEEncryptor<heongpu::Scheme::BFV> encryptor(context, public_key);
27 heongpu::HEDecryptor<heongpu::Scheme::BFV> decryptor(context, secret_key);
28 heongpu::HEArithmeticOperator<heongpu::Scheme::BFV> operators(context, encoder);
29
30 // 5. Create a message and encode it into a plaintext
31 std::vector<uint64_t> message(poly_modulus_degree, 8ULL);
32 heongpu::Plaintext<heongpu::Scheme::BFV> P1(context);
33 encoder.encode(P1, message);
34
35 // 6. Encrypt the plaintext into a ciphertext
36 heongpu::Ciphertext<heongpu::Scheme::BFV> C1(context);
37 encryptor.encrypt(C1, P1);
38
39 // 7. Perform a homomorphic operation (in-place addition)
40 operators.add_inplace(C1, C1); // Result: 8 + 8 = 16
41
42 // 8. Decrypt the result
43 heongpu::Plaintext<heongpu::Scheme::BFV> P2(context);
44 decryptor.decrypt(P2, C1);
45
46 // 9. Decode the plaintext to retrieve the final vector
47 std::vector<uint64_t> result;
48 encoder.decode(result, P2);
49
50 // The 'result' vector should now contain the value 16 in all its slots.
51 return 0;
52 }