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_ARCHITECTURES variable 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 XX with the appropriate value from the table below. For example, for an NVIDIA RTX 4090 (Ada Lovelace architecture), you would use 89.

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 -jN flag will use multiple cores to speed up compilation. Replace N by the number of your logical cores (i.e. the output of nproc).

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 }