Getting Started

SDK-GS-001 v1.0

This guide walks you through installing the QuantaCore SDK, discovering QUAC 100 devices, and performing your first post-quantum cryptographic operation — all in under five minutes. Whether you have physical hardware or are using the software simulator, the API experience is identical.

Overview #

The Dyber Cryptographic API is the software interface to the QUAC 100 Post-Quantum Cryptographic Accelerator. It provides a layered architecture with multiple integration points depending on your deployment requirements:

API LayerLibraryLatency OverheadBest For
Native C APIlibquac100<100 nsMaximum performance, low-level control
Language Bindingsquac100-{lang}100–500 nsApplication development in Rust, Python, Java, Go, C#, Node.js
OpenSSL Providerquac100-ossl.so1–5 μsTransparent TLS/SSL acceleration, zero code changes
PKCS#11 Modulelibquac100_pkcs11.so2–10 μsHSM replacement, certificate authority, token operations
Windows CNGquac100cng.dll2–10 μsNative Windows cryptographic infrastructure

All layers ultimately communicate with the same hardware through the kernel driver (quac100.ko on Linux, quac100.sys on Windows). The native C API provides the foundation that all other layers build upon.

Prerequisites #

Hardware (optional): QUAC 100 PCIe accelerator card installed in a PCIe Gen4/Gen5 x16 slot. The software simulator provides full API compatibility for development without hardware.

Operating System: Linux (Ubuntu 22.04+, RHEL 8+, SLES 15+) or Windows (Server 2019+, Windows 10/11). Linux kernel 5.15+ recommended for optimal DMA performance.

Compiler Toolchain: GCC 11+ or Clang 14+ on Linux, MSVC 2019+ on Windows. CMake 3.16+ for the build system. Language-specific toolchains as needed (Rust 1.70+, Python 3.8+, JDK 11+, Go 1.20+).

Driver: QUAC 100 kernel driver must be loaded before the SDK can communicate with hardware. The driver is included in the SDK package and installs via standard package managers.

# Check if driver is loaded (Linux)
$ lsmod | grep quac100
quac100               524288  0

# Check device presence
$ lspci | grep Dyber
b3:00.0 Encryption controller: Dyber Inc. QUAC 100 PQC Accelerator (rev 01)

Installation #

Linux (Debian/Ubuntu):

# Add Dyber repository
$ curl -fsSL https://packages.dyber.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/dyber.gpg
$ echo "deb [signed-by=/usr/share/keyrings/dyber.gpg] https://packages.dyber.com/apt stable main" | \
    sudo tee /etc/apt/sources.list.d/dyber.list

# Install SDK and driver
$ sudo apt update
$ sudo apt install quac100-sdk quac100-dkms

# Load driver
$ sudo modprobe quac100

# Verify installation
$ quac100-info
QuantaCore SDK v1.0.0
Devices found: 1
  Device 0: QUAC 100 [FW v2.1.0] Serial: QC-2025-00142

Linux (RHEL/Rocky):

$ sudo dnf config-manager --add-repo https://packages.dyber.com/rpm/dyber.repo
$ sudo dnf install quac100-sdk quac100-kmod

Windows:

:: Download and run the MSI installer
> QuantaCoreSDK-1.0.0-x64.msi

:: Or via WinGet
> winget install Dyber.QuantaCoreSDK

From Source:

$ git clone https://github.com/dyber-inc/quantacore-sdk.git
$ cd quantacore-sdk
$ mkdir build && cd build
$ cmake .. -DBUILD_SIMULATOR=ON -DBUILD_TESTS=ON
$ make -j$(nproc)
$ sudo make install

Device Discovery #

The SDK automatically discovers all QUAC 100 devices connected to the system. Each physical card appears as one device, with SR-IOV virtual functions appearing as additional devices when configured for multi-tenant operation.

#include <quac100.h>

int main(void) {
    // Initialize the SDK
    quac_result_t rc = quac_init();
    if (rc != QUAC_SUCCESS) {
        fprintf(stderr, "SDK init failed: %s\n", quac_strerror(rc));
        return 1;
    }

    // Discover devices
    uint32_t count = quac_device_count();
    printf("Found %u QUAC 100 device(s)\n", count);

    for (uint32_t i = 0; i < count; i++) {
        quac_device_t dev;
        rc = quac_open(i, &dev);
        if (rc == QUAC_SUCCESS) {
            quac_device_info_t info;
            quac_get_info(dev, &info);
            printf("  Device %u: FW %s, Serial %s\n",
                   i, info.firmware_version, info.serial_number);
            quac_close(dev);
        }
    }

    quac_shutdown();
    return 0;
}

The quac_init() function must be called once before any other SDK function. It initializes internal data structures, scans for hardware, and establishes driver communication channels. Call quac_shutdown() when finished to release all resources.

First Cryptographic Operation #

The simplest meaningful operation is an ML-KEM (Kyber) key exchange. This demonstrates the full lifecycle: key generation, encapsulation (sender side), and decapsulation (receiver side).

quac_device_t dev;
quac_open(0, &dev);

// Generate ML-KEM-768 key pair
quac_kem_keypair_t keypair;
quac_kem_keygen(dev, QUAC_ALG_KYBER_768, &keypair);

// Sender: encapsulate a shared secret using the public key
quac_kem_ciphertext_t ct;
quac_kem_shared_secret_t sender_ss;
quac_kem_encapsulate(dev, &keypair.public_key, &ct, &sender_ss);

// Receiver: decapsulate using the secret key
quac_kem_shared_secret_t receiver_ss;
quac_kem_decapsulate(dev, &keypair.secret_key, &ct, &receiver_ss);

// Both sides now share the same 32-byte secret
assert(memcmp(sender_ss.data, receiver_ss.data, 32) == 0);

// Secure cleanup
quac_zeroize(&keypair, sizeof(keypair));
quac_close(dev);

On QUAC 100 hardware, this entire sequence completes in under 5 microseconds. The software simulator produces identical results but with higher latency (~1ms).

Software Simulator #

The QuantaCore SDK ships with a full-featured software simulator (libquac100_sim) that implements every API function using reference C implementations of ML-KEM, ML-DSA, and SLH-DSA. The simulator enables development and testing without QUAC 100 hardware.

// Enable simulator mode before quac_init()
quac_set_simulator_mode(true);
quac_init();

// All API calls now work against the software simulator
// Cryptographic results are identical to hardware
quac_device_t dev;
quac_open(0, &dev);  // Opens a simulated device

// Check if running on hardware or simulator
bool is_hw = quac_is_hardware();
printf("Running on: %s\n", is_hw ? "QUAC 100 hardware" : "Software simulator");

// Optionally configure simulator timing behavior
quac_simulator_config(10, 50000);  // 10μs latency, 50K ops/sec
Environment variable control: Set QUAC_SIMULATOR=1 in your environment to force simulator mode without code changes. This is useful for CI/CD pipelines where hardware may not be available.

The simulator is API-compatible in every respect: the same function signatures, the same error codes, the same cryptographic output for the same inputs. The only difference is performance — hardware delivers sub-microsecond operations while the simulator operates at software speeds.

Project Setup #

CMake (C/C++):

cmake_minimum_required(VERSION 3.16)
project(my_pqc_app LANGUAGES C)

find_package(Quac100 REQUIRED)

add_executable(my_app src/main.c)
target_link_libraries(my_app PRIVATE Quac100::quac100)

pkg-config:

$ gcc -o my_app main.c $(pkg-config --cflags --libs quac100)

Rust (Cargo.toml):

[dependencies]
quac100 = "1.0"

Python:

$ pip install quac100

Java (Maven pom.xml):

<dependency>
  <groupId>com.dyber</groupId>
  <artifactId>quac100</artifactId>
  <version>1.0.0</version>
</dependency>

Go:

$ go get github.com/dyber-inc/quac100-go@v1.0.0

Error Handling #

Every SDK function returns a quac_result_t status code. The SDK defines a structured error hierarchy that distinguishes between device errors, cryptographic failures, resource exhaustion, and parameter validation issues.

Error CodeValueDescription
QUAC_SUCCESS0x0000Operation completed successfully
QUAC_ERR_NOT_INITIALIZED0x0001SDK not initialized — call quac_init() first
QUAC_ERR_DEVICE_NOT_FOUND0x0010No device at specified index
QUAC_ERR_DEVICE_BUSY0x0011Device is processing another request
QUAC_ERR_INVALID_PARAM0x0020Invalid parameter passed to function
QUAC_ERR_BUFFER_TOO_SMALL0x0021Output buffer insufficient
QUAC_ERR_CRYPTO_FAILED0x0030Cryptographic operation failed validation
QUAC_ERR_KEY_INVALID0x0031Key material is malformed or expired
QUAC_ERR_HW_FAULT0x0040Hardware fault detected — device needs reset
QUAC_ERR_SELFTEST_FAILED0x0041POST or continuous self-test failure
quac_result_t rc = quac_kem_keygen(dev, QUAC_ALG_KYBER_768, &keypair);
if (rc != QUAC_SUCCESS) {
    fprintf(stderr, "Key generation failed: %s (0x%04X)\n",
            quac_strerror(rc), rc);
    // quac_strerror() returns a human-readable error string
    // Thread-safe, returns pointer to static string
}

Complete Example: hello_quac #

The hello_quac example demonstrates initialization, device discovery, a complete ML-KEM key exchange, an ML-DSA signature cycle, QRNG random byte generation, and cleanup. It compiles and runs identically on hardware and simulator.

#include <quac100.h>
#include <stdio.h>
#include <string.h>

int main(void) {
    // Initialize (auto-detects hardware vs simulator)
    quac_init();

    quac_device_t dev;
    quac_open(0, &dev);

    quac_device_info_t info;
    quac_get_info(dev, &info);
    printf("Device: %s (FW %s)\n", info.product_name, info.firmware_version);
    printf("Mode: %s\n\n", quac_is_hardware() ? "Hardware" : "Simulator");

    // ── ML-KEM-768 Key Exchange ──
    quac_kem_keypair_t kem_kp;
    quac_kem_keygen(dev, QUAC_ALG_KYBER_768, &kem_kp);

    quac_kem_ciphertext_t ct;
    quac_kem_shared_secret_t ss_enc, ss_dec;
    quac_kem_encapsulate(dev, &kem_kp.public_key, &ct, &ss_enc);
    quac_kem_decapsulate(dev, &kem_kp.secret_key, &ct, &ss_dec);

    printf("ML-KEM-768: %s\n",
           memcmp(ss_enc.data, ss_dec.data, 32) == 0 ? "PASS" : "FAIL");

    // ── ML-DSA-65 Digital Signature ──
    quac_sign_keypair_t sig_kp;
    quac_sign_keygen(dev, QUAC_ALG_DILITHIUM_3, &sig_kp);

    uint8_t message[] = "Hello, post-quantum world!";
    quac_signature_t sig;
    quac_sign(dev, &sig_kp.secret_key, message, sizeof(message), &sig);

    bool valid;
    quac_verify(dev, &sig_kp.public_key, message, sizeof(message), &sig, &valid);
    printf("ML-DSA-65:  %s\n", valid ? "PASS" : "FAIL");

    // ── QRNG Random Bytes ──
    uint8_t random[32];
    quac_random_bytes(dev, random, 32);
    printf("QRNG:       ");
    for (int i = 0; i < 8; i++) printf("%02x", random[i]);
    printf("...\n");

    // Cleanup
    quac_zeroize(&kem_kp, sizeof(kem_kp));
    quac_zeroize(&sig_kp, sizeof(sig_kp));
    quac_close(dev);
    quac_shutdown();

    printf("\nAll operations completed successfully.\n");
    return 0;
}

Build and run:

$ gcc -o hello_quac hello_quac.c -lquac100
$ ./hello_quac
Device: QUAC 100 PQC Accelerator (FW 2.1.0)
Mode: Hardware

ML-KEM-768: PASS
ML-DSA-65:  PASS
QRNG:       a3f7c21b9e4d06f8...

All operations completed successfully.

Next Steps #

With the SDK installed and your first cryptographic operations running, you're ready to explore deeper integration paths. The Universal API page covers the algorithm-agnostic abstraction layer that enables crypto-agility across all supported algorithms. For drop-in acceleration of existing applications, see the OpenSSL Provider or PKCS#11 Interface documentation. If you're developing in a language other than C, the Language Bindings page provides idiomatic APIs for Rust, Python, Java, Go, C#, and Node.js.

Need help? The SDK ships with comprehensive example applications in the examples/ directory. Each example includes a Makefile and README with detailed build and usage instructions. For technical support, contact support@dyber.com.