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#
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.gzExtract 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
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:
cuPQC-BigInt API Reference - cuPQC-BigInt API documentation
cuPQC-NTT API Reference - cuPQC-NTT API documentation
cuPQC-Hash API Reference - cuPQC-Hash API documentation
cuPQC-PK API Reference - cuPQC-PK API documentation