Getting Started#

The cuPQC SDK provides device-side libraries for integrating cryptographic operations directly into your CUDA kernels. This guide will help you get started with the SDK in just a few steps.

Download and Installation#

  1. Download the SDK

    Download the cuPQC SDK from the NVIDIA cuPQC SDK website:

    wget https://developer.download.nvidia.com/compute/cupqc/redist/cupqc/cupqc-sdk-<version>.tar.gz
    
  2. Extract the Package

    Extract the tarball to your desired location:

    tar -xzf cupqc-sdk-<version>.tar.gz -C <your_directory>
    

    After extraction, the SDK structure will be:

    • <your_directory>/include/cupqc/ - SDK header files (bigint.hpp, ntt.hpp, hash.hpp, pk.hpp, etc.)

    • <your_directory>/include/commondx/ - CommonDx headers (required dependency)

    • <your_directory>/lib/ - Static libraries (libcupqc-bigint.a, libcupqc-ntt.a, libcupqc-hash.a, libcupqc-pk.a)

    • <your_directory>/cmake/ - CMake configuration files

    • <your_directory>/examples/ - Example programs

  3. Verify Installation

    Check that the headers are accessible:

    ls <your_directory>/include/cupqc/
    # You should see: bigint.hpp, ntt.hpp, hash.hpp, pk.hpp, database.hpp, operators.hpp, etc.
    

Understanding the Libraries#

The SDK provides four libraries that can be used together or independently:

cuPQC-BigInt (Multi-Precision Integer Arithmetic)
  • Fixed-width unsigned big-integer arithmetic, including modular operations

  • Single-thread or warp-cooperative (TPI) execution for widths from 32 bits up to 4096

cuPQC-NTT (Number Theoretic Transform)
  • Forward and inverse NTT for modular arithmetic in CUDA kernels

  • Support for any custom prime, with built-in BabyBear / KoalaBear primes and constants

cuPQC-Hash (Cryptographic Hash Functions)
  • SHA-2, SHA-3, SHAKE and Poseidon2 hash functions

  • Merkle Tree API

cuPQC-PK (Public Key)
  • ML-KEM (key encapsulation)

  • ML-DSA (digital signatures)

  • NIST-standardized post-quantum algorithms

All four libraries are device-side extensions that integrate directly into your CUDA kernels.

Basic Workflow#

1. Include the Library Headers#

In your CUDA source file:

#include <bigint.hpp> // For cuPQC-BigInt
#include <ntt.hpp>    // For cuPQC-NTT
#include <hash.hpp>   // For cuPQC-Hash
#include <pk.hpp>     // For cuPQC-PK

2. Define Your Descriptors#

Use operators to describe your cryptographic operations:

// Example: 256-bit big integer owned by a single thread
using BI256 = decltype(BitWidth<256>() + SM<800>() + Thread());

// Example: forward NTT (size 1024, block execution)
using ForwardNTT1024 = decltype(Algorithm<algorithm::NTT>()
                                + Direction<nttDirection::FORWARD>()
                                + Precision<uint32_t>()
                                + Size<1024>()
                                + Block()
                                + BlockDim<128>());

// Example: SHA3-256 with thread-based execution
using SHA3_256_Thread = decltype(SHA3_256() + Thread());

// Example: ML-KEM-512 Key Generation with 128 threads
using MLKEM512Key = decltype(ML_KEM_512()
                           + Function<function::Keygen>()
                           + Block()
                           + BlockDim<128>());

3. Write Your CUDA Kernel#

Call library functions directly in your kernel:

__global__ void my_crypto_kernel(/* parameters */) {
    MLKEM512Key().execute(/* arguments */);
    // ForwardNTT1024().execute(/* arguments */);  // cuPQC-NTT example
    // Fuse with other GPU operations
}

4. Compile Your Application#

The cuPQC SDK uses Link-Time Optimization (LTO). Compile with these flags:

Using nvcc directly:

nvcc -std=c++17 -dlto -arch=sm_XY \\
     -I<your_directory>/include \\
     -L<your_directory>/lib -lcupqc-<lib> \\
     your_program.cu -o your_program

Replace sm_XY with your GPU architecture (sm_80, sm_86, sm_89, sm_90). Replace <lib> with the library you are using (bigint, ntt, hash, or pk).

5. Run and Verify#

Execute your compiled program:

./your_program

Check the example programs in <your_directory>/examples/ for complete working code.

Using cuPQC with CMake#

The cuPQC SDK provides configuration files that simplify integration into CMake projects. The config files are located in <your_directory>/cmake/.

Find the cupqc package:

find_package(cupqc REQUIRED)

Link with the cuPQC-BigInt library:

target_link_libraries(YourProgram PRIVATE cupqc-bigint_static)

Link with the cuPQC-NTT library:

target_link_libraries(YourProgram PRIVATE cupqc-ntt_static)

Link with the cuPQC-Hash library:

target_link_libraries(YourProgram PRIVATE cupqc-hash_static)

Link with the cuPQC-PK library:

target_link_libraries(YourProgram PRIVATE cupqc-pk_static)

Link with multiple libraries:

target_link_libraries(YourProgram PRIVATE cupqc-bigint_static cupqc-ntt_static cupqc-hash_static cupqc-pk_static)

Build your project by setting the CMAKE_PREFIX_PATH to your SDK directory:

cmake -DCMAKE_PREFIX_PATH=<your_directory>/cmake ..
make

Next Steps#

Detailed Implementation Guides:

  • cuPQC-BigInt Usage - Complete guide with bigint descriptors, arithmetic, and modular reduction

  • cuPQC-NTT Usage - Complete guide with NTT descriptors, twiddle factors, and execution

  • cuPQC-Hash Usage - Complete guide with hash function and Merkle Tree examples

  • cuPQC-PK Usage - Complete guide with ML-KEM and ML-DSA examples

API Reference: