API Reference
Complete C API reference for libquac100. All functions are declared in <quac100/quac100.h>. Thread safety, memory ownership, and FIPS applicability are noted for each function. Functions marked [FIPS] are available in FIPS 140-3 mode; those marked [Permissive] are restricted to permissive mode only.
Overview #
The libquac100 API is organized into functional groups. All functions return quac_status_t unless otherwise noted. Output buffers are always caller-allocated. The API is fully re-entrant and thread-safe — multiple threads can share a single quac_device_t handle without external locking.
| Group | Header | Functions | Description |
|---|---|---|---|
| Core | quac100.h | 12 | Init, shutdown, device open/close, versioning |
| KEM | quac100_kem.h | 8 | Key encapsulation: keygen, encaps, decaps, hybrid |
| Signature | quac100_sig.h | 8 | Digital signatures: keygen, sign, verify, hybrid |
| Random | quac100_rand.h | 6 | QRNG, DRBG, seed management |
| Key Mgmt | quac100_keymgmt.h | 14 | Persistent keys, wrapping, lifecycle |
| Async | quac100_async.h | 16 | Async submission, batch, callbacks, queue mgmt |
| Diagnostics | quac100_diag.h | 10 | Device info, health, POST, audit, temperature |
Conventions #
Return Values
All functions return quac_status_t (int32_t). A return value of QUAC_OK (0) indicates success. Negative values indicate errors. Use quac_strerror() to convert error codes to human-readable strings.
Memory Ownership
The caller owns all input and output buffers. The SDK never allocates memory on behalf of the caller. Output buffers must be large enough to hold the result — use the quac_*_output_size() helper functions to query required sizes. Input buffers can be freed or reused immediately after the synchronous call returns.
Thread Safety
All functions are safe to call concurrently from multiple threads on the same quac_device_t handle. The SDK uses internal lock-free ring buffers for hardware communication. No external synchronization is required.
Naming Convention
Functions follow the pattern quac_{group}_{action}. Types follow quac_{group}_{noun}_t. Constants follow QUAC_{GROUP}_{NAME}.
Initialization & Device #
quac_init
quac_status_t quac_init(void);
Initialize the QuantaCore SDK. Must be called once before any other SDK function. Loads the kernel driver interface, initializes internal thread pools, and performs library self-checks. [FIPS] Thread-safe (uses internal once-initialization).
quac_init_ex
quac_status_t quac_init_ex(const quac_init_config_t *config);
Extended initialization with configuration options. Allows setting log level, log callback, memory allocator overrides, and thread pool sizes. Pass NULL for defaults (equivalent to quac_init()). [FIPS]
| Field | Type | Default | Description |
|---|---|---|---|
log_level | quac_log_level_t | QUAC_LOG_WARN | Minimum log severity |
log_callback | quac_log_cb_t | NULL (stderr) | Custom log handler |
alloc | quac_allocator_t* | NULL (malloc/free) | Custom memory allocator |
async_threads | uint32_t | 4 | Completion callback thread pool size |
quac_shutdown
quac_status_t quac_shutdown(void);
Shut down the SDK and release all resources. All device handles must be closed before calling. Waits for pending async operations to complete (up to 5 seconds). [FIPS]
quac_open
quac_device_t *quac_open(uint32_t device_index);
Open a QUAC 100 device by index (0-based). Returns a device handle on success, NULL on failure. Call quac_get_last_error() to retrieve the error code. The returned handle is thread-safe. [FIPS]
quac_open_ex
quac_device_t *quac_open_ex(uint32_t device_index, const quac_device_config_t *config);
Extended device open with configuration. Allows setting queue depth, interrupt coalescing, DMA preferences, NUMA affinity, and callback thread configuration. [FIPS]
quac_close
quac_status_t quac_close(quac_device_t *dev);
Close a device handle. Zeroizes all ephemeral session keys, waits for in-flight async operations, and releases kernel resources. The handle is invalid after this call. [FIPS]
quac_enumerate
quac_status_t quac_enumerate(quac_device_info_t *devices, size_t max_devices, size_t *n_found);
Enumerate all QUAC 100 devices in the system. Populates the devices array with device index, PCIe BDF address, serial number, firmware version, and operational status. Does not require quac_open(). [FIPS]
quac_get_version
const char *quac_get_version(void);
Return the SDK version string (e.g., "1.2.0"). Does not require initialization. [FIPS]
quac_get_version_numeric
uint32_t quac_get_version_numeric(void);
Return the SDK version as a packed integer: (major << 16) | (minor << 8) | patch. Useful for compile-time version checks. [FIPS]
KEM Functions #
quac_kem_keygen
quac_status_t quac_kem_keygen(quac_device_t *dev, quac_kem_alg_t alg, quac_kem_keypair_t *kp);
Generate a KEM key pair. The private key and public key are written to kp. Key material is generated using hardware QRNG. [FIPS] for ML-KEM-512/768/1024.
| Algorithm | Constant | PK Size | SK Size |
|---|---|---|---|
| ML-KEM-512 | QUAC_KEM_ML_KEM_512 | 800 bytes | 1,632 bytes |
| ML-KEM-768 | QUAC_KEM_ML_KEM_768 | 1,184 bytes | 2,400 bytes |
| ML-KEM-1024 | QUAC_KEM_ML_KEM_1024 | 1,568 bytes | 3,168 bytes |
quac_kem_encaps
quac_status_t quac_kem_encaps(quac_device_t *dev, quac_kem_alg_t alg,
const uint8_t *pk, size_t pk_len,
uint8_t *ct, size_t *ct_len,
uint8_t *ss, size_t *ss_len);
Encapsulate a shared secret using the recipient's public key. Writes ciphertext to ct and shared secret to ss. The shared secret is always 32 bytes for all ML-KEM parameter sets. [FIPS]
quac_kem_decaps
quac_status_t quac_kem_decaps(quac_device_t *dev, quac_kem_alg_t alg,
const uint8_t *sk, size_t sk_len,
const uint8_t *ct, size_t ct_len,
uint8_t *ss, size_t *ss_len);
Decapsulate a shared secret using the private key and ciphertext. Implements implicit rejection — if decapsulation fails, a deterministic but unpredictable shared secret is returned (no error code distinguishes valid from invalid ciphertext). [FIPS]
quac_kem_output_size
quac_status_t quac_kem_output_size(quac_kem_alg_t alg,
size_t *ct_size, size_t *ss_size);
Query the ciphertext and shared secret sizes for a given KEM algorithm. Use to allocate output buffers before calling quac_kem_encaps(). [FIPS]
quac_kem_hybrid_encaps
quac_status_t quac_kem_hybrid_encaps(quac_device_t *dev,
quac_kem_alg_t pq_alg, const uint8_t *pq_pk, size_t pq_pk_len,
quac_kem_classical_t classical_alg, const uint8_t *classical_pk, size_t classical_pk_len,
quac_hybrid_mode_t mode,
uint8_t *ct, size_t *ct_len,
uint8_t *ss, size_t *ss_len);
Perform hybrid KEM encapsulation combining a post-quantum and classical algorithm. The shared secret is derived by concatenating and hashing both component secrets using HKDF-SHA3-256. Supported classical algorithms: QUAC_KEM_X25519, QUAC_KEM_X448, QUAC_KEM_ECDH_P256, QUAC_KEM_ECDH_P384. [FIPS]
quac_kem_hybrid_decaps
quac_status_t quac_kem_hybrid_decaps(quac_device_t *dev,
quac_kem_alg_t pq_alg, const uint8_t *pq_sk, size_t pq_sk_len,
quac_kem_classical_t classical_alg, const uint8_t *classical_sk, size_t classical_sk_len,
quac_hybrid_mode_t mode,
const uint8_t *ct, size_t ct_len,
uint8_t *ss, size_t *ss_len);
Hybrid KEM decapsulation. Counterpart to quac_kem_hybrid_encaps(). [FIPS]
Signature Functions #
quac_sig_keygen
quac_status_t quac_sig_keygen(quac_device_t *dev, quac_sig_alg_t alg, quac_sig_keypair_t *kp);
Generate a signature key pair. [FIPS] for ML-DSA and SLH-DSA parameter sets.
| Algorithm | Constant | PK Size | SK Size | Sig Size |
|---|---|---|---|---|
| ML-DSA-44 | QUAC_SIG_ML_DSA_44 | 1,312 B | 2,560 B | 2,420 B |
| ML-DSA-65 | QUAC_SIG_ML_DSA_65 | 1,952 B | 4,032 B | 3,309 B |
| ML-DSA-87 | QUAC_SIG_ML_DSA_87 | 2,592 B | 4,896 B | 4,627 B |
| SLH-DSA-128s | QUAC_SIG_SLH_DSA_128S | 32 B | 64 B | 7,856 B |
| SLH-DSA-128f | QUAC_SIG_SLH_DSA_128F | 32 B | 64 B | 17,088 B |
| SLH-DSA-192s | QUAC_SIG_SLH_DSA_192S | 48 B | 96 B | 16,224 B |
| SLH-DSA-256s | QUAC_SIG_SLH_DSA_256S | 64 B | 128 B | 29,792 B |
quac_sign
quac_status_t quac_sign(quac_device_t *dev, quac_sig_alg_t alg,
const uint8_t *sk, size_t sk_len,
const uint8_t *msg, size_t msg_len,
uint8_t *sig, size_t *sig_len);
Sign a message. The signature is written to sig and the actual length to *sig_len. For ML-DSA, signing is randomized (nonce generated from QRNG). For SLH-DSA, signing is deterministic. [FIPS]
quac_verify
quac_status_t quac_verify(quac_device_t *dev, quac_sig_alg_t alg,
const uint8_t *pk, size_t pk_len,
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len);
Verify a signature. Returns QUAC_OK if the signature is valid, QUAC_ERR_VERIFY_FAILED if invalid. The function is constant-time — the return time does not depend on whether the signature is valid. [FIPS]
quac_sign_hybrid
quac_status_t quac_sign_hybrid(quac_device_t *dev,
quac_sig_alg_t pq_alg, const uint8_t *pq_sk, size_t pq_sk_len,
quac_sig_classical_t classical_alg, const uint8_t *classical_sk, size_t classical_sk_len,
quac_hybrid_mode_t mode,
const uint8_t *msg, size_t msg_len,
uint8_t *sig, size_t *sig_len);
Create a hybrid signature combining PQ and classical algorithms. The output format concatenates both signatures with a type header. [FIPS]
quac_verify_hybrid
quac_status_t quac_verify_hybrid(quac_device_t *dev,
quac_sig_alg_t pq_alg, const uint8_t *pq_pk, size_t pq_pk_len,
quac_sig_classical_t classical_alg, const uint8_t *classical_pk, size_t classical_pk_len,
quac_hybrid_mode_t mode,
const uint8_t *msg, size_t msg_len,
const uint8_t *sig, size_t sig_len);
Verify a hybrid signature. In QUAC_HYBRID_BOTH mode, both signatures must be valid. In QUAC_HYBRID_EITHER, at least one must be valid. [FIPS]
quac_sig_output_size
quac_status_t quac_sig_output_size(quac_sig_alg_t alg, size_t *sig_size);
Query the maximum signature size for a given algorithm. [FIPS]
Random Generation #
quac_random
quac_status_t quac_random(quac_device_t *dev, uint8_t *buf, size_t len);
Generate cryptographically secure random bytes using the hardware QRNG source passed through the SP 800-90A CTR_DRBG. This is the recommended function for all general-purpose random number generation. [FIPS]
quac_random_raw
quac_status_t quac_random_raw(quac_device_t *dev, uint8_t *buf, size_t len);
Generate raw quantum random bytes directly from the QRNG entropy source, bypassing the DRBG. Output passes SP 800-90B continuous health tests. Maximum 1 MB per call. [Permissive] — raw QRNG output is not FIPS-approved without DRBG conditioning.
quac_random_seed
quac_status_t quac_random_seed(quac_device_t *dev, const uint8_t *additional_input, size_t len);
Provide additional entropy input to the DRBG. This is mixed with the QRNG seed, not used as the sole seed source. Useful for incorporating application-specific entropy. [FIPS]
quac_random_reseed
quac_status_t quac_random_reseed(quac_device_t *dev);
Force an immediate DRBG reseed from the QRNG source. The DRBG automatically reseeds every 2^48 generate calls; this function triggers an early reseed. [FIPS]
quac_random_health
quac_status_t quac_random_health(quac_device_t *dev, quac_rng_health_t *health);
Query the health status of the QRNG entropy source and DRBG. Returns entropy rate estimate, continuous health test results, and reseed counter. [FIPS]
| Field | Type | Description |
|---|---|---|
entropy_rate_bps | double | Estimated entropy rate in bits per sample |
health_test_passed | bool | SP 800-90B continuous health test status |
repetition_count_ok | bool | Repetition count test status |
adaptive_proportion_ok | bool | Adaptive proportion test status |
drbg_reseed_counter | uint64_t | Number of generate calls since last reseed |
total_bytes_generated | uint64_t | Total random bytes generated since power-on |
Key Management #
quac_key_generate
quac_status_t quac_key_generate(quac_device_t *dev, const quac_key_attrs_t *attrs, quac_key_handle_t *handle);
Generate a persistent key stored within the hardware cryptographic boundary. The key is identified by the returned handle and optionally by the label set in attrs. [FIPS]
quac_key_import
quac_status_t quac_key_import(quac_device_t *dev, const quac_key_attrs_t *attrs,
const uint8_t *key_data, size_t key_len, quac_key_handle_t *handle);
Import a key from external material. In FIPS mode, only wrapped (encrypted) key data is accepted. In permissive mode, plaintext keys can be imported. [FIPS] (wrapped only)
quac_key_find
quac_status_t quac_key_find(quac_device_t *dev, const char *label, quac_key_handle_t *handle);
Find a persistent key by its label. Returns QUAC_ERR_NOT_FOUND if no key with the given label exists. [FIPS]
quac_key_get_info
quac_status_t quac_key_get_info(quac_key_handle_t handle, quac_key_info_t *info);
Query metadata about a key: algorithm, usage flags, lifecycle state, creation time, expiration, and label. Does not expose key material. [FIPS]
quac_key_get_state
quac_status_t quac_key_get_state(quac_key_handle_t handle, quac_key_state_t *state);
Query the lifecycle state of a key. [FIPS]
quac_key_activate / quac_key_deactivate / quac_key_suspend
quac_status_t quac_key_activate(quac_key_handle_t handle);
quac_status_t quac_key_deactivate(quac_key_handle_t handle);
quac_status_t quac_key_suspend(quac_key_handle_t handle);
Transition a key through lifecycle states. Invalid transitions return QUAC_ERR_INVALID_STATE. [FIPS]
quac_key_destroy
quac_status_t quac_key_destroy(quac_key_handle_t handle);
Permanently destroy a key. Key material is zeroized using 3-pass overwrite with verification. The handle is invalid after this call. [FIPS]
quac_key_wrap / quac_key_unwrap
quac_status_t quac_key_wrap(quac_key_handle_t key, quac_key_handle_t wrapping_key,
quac_wrap_alg_t alg, uint8_t *out, size_t out_cap, size_t *out_len);
quac_status_t quac_key_unwrap(quac_device_t *dev, quac_key_handle_t wrapping_key,
quac_wrap_alg_t alg, const uint8_t *data, size_t data_len,
const quac_key_attrs_t *attrs, quac_key_handle_t *handle);
Wrap (export) or unwrap (import) a key using AES Key Wrap with Padding (AES-KWP). The wrapping key must be stored in hardware. [FIPS]
quac_key_enumerate
quac_status_t quac_key_enumerate(quac_device_t *dev,
quac_key_handle_t *handles, size_t max_handles, size_t *n_found);
List all persistent keys stored on the device. [FIPS]
quac_key_get_public
quac_status_t quac_key_get_public(quac_key_handle_t handle,
uint8_t *pk, size_t pk_cap, size_t *pk_len);
Extract the public key component from a persistent key pair. Public key extraction is always permitted regardless of the key's extractable attribute. [FIPS]
Async & Batch Functions #
quac_async_submit
quac_status_t quac_async_submit(quac_device_t *dev, const quac_async_desc_t *desc, quac_job_t *job);
Submit an asynchronous operation. Returns immediately. The job handle is written to *job. [FIPS]
quac_async_poll
quac_job_status_t quac_async_poll(quac_job_t job);
Non-blocking status check. Returns QUAC_JOB_PENDING, QUAC_JOB_COMPLETED, QUAC_JOB_FAILED, or QUAC_JOB_CANCELLED. [FIPS]
quac_async_wait / quac_async_wait_any
quac_status_t quac_async_wait(quac_job_t job, uint32_t timeout_ms);
quac_status_t quac_async_wait_any(quac_job_t *jobs, size_t n_jobs, size_t *completed_idx, uint32_t timeout_ms);
Block until a job (or any of several jobs) completes. timeout_ms = 0 means infinite wait. Returns QUAC_ERR_TIMEOUT if timeout expires. [FIPS]
quac_async_cancel
quac_status_t quac_async_cancel(quac_job_t job);
Cancel a pending job. Returns QUAC_ERR_IN_PROGRESS if already executing on hardware. [FIPS]
quac_async_release
quac_status_t quac_async_release(quac_job_t job);
Release a job handle after retrieving its result. Must be called for every completed job. [FIPS]
quac_async_get_event_fd
int quac_async_get_event_fd(quac_device_t *dev);
Get a file descriptor that becomes readable when completions are available. Suitable for epoll/kqueue/io_uring integration. [FIPS]
quac_async_reap
quac_status_t quac_async_reap(quac_device_t *dev, quac_job_t *completed, size_t max, size_t *n_completed);
Harvest completed jobs after the event FD signals. Non-blocking. [FIPS]
quac_batch_submit / quac_batch_submit_ex
quac_status_t quac_batch_submit(quac_device_t *dev, const quac_batch_desc_t *descs, size_t n, quac_batch_t *batch);
quac_status_t quac_batch_submit_ex(quac_device_t *dev, const quac_batch_desc_t *descs, size_t n,
const quac_batch_opts_t *opts, quac_batch_t *batch);
Submit a batch of operations. The extended version accepts options for ordering, atomicity, progress callbacks, and DMA coalescing. [FIPS]
quac_batch_wait / quac_batch_release
quac_status_t quac_batch_wait(quac_batch_t batch, uint32_t timeout_ms);
quac_status_t quac_batch_release(quac_batch_t batch);
Wait for all operations in a batch to complete, then release the batch handle. [FIPS]
Diagnostics & Info #
quac_get_device_info
quac_status_t quac_get_device_info(quac_device_t *dev, quac_device_info_t *info);
Query comprehensive device information: model, serial number, firmware version, PCIe link status, temperature, power consumption, uptime, and total operations count. [FIPS]
quac_get_fips_status
quac_status_t quac_get_fips_status(quac_device_t *dev, quac_fips_status_t *status);
Query FIPS 140-3 operational mode, self-test status, certificate number, and security policy version. [FIPS]
quac_get_temperature
quac_status_t quac_get_temperature(quac_device_t *dev, quac_temp_info_t *temp);
Read current, minimum, maximum, and threshold temperatures from on-chip sensors. [FIPS]
quac_get_performance_counters
quac_status_t quac_get_performance_counters(quac_device_t *dev, quac_perf_counters_t *counters);
Read hardware performance counters: total operations by type, average latency per algorithm, queue utilization, DMA transfer statistics, and PCIe bandwidth usage. [FIPS]
quac_strerror
const char *quac_strerror(quac_status_t status);
Convert an error code to a human-readable string. Thread-safe (returns pointer to static string). [FIPS]
quac_zeroize
void quac_zeroize(void *ptr, size_t len);
Securely zero memory with a compiler barrier to prevent optimization. Use for host-side sensitive data after use. [FIPS]
Error Codes #
| Code | Constant | Description |
|---|---|---|
| 0 | QUAC_OK | Operation completed successfully |
| -1 | QUAC_ERR_INVALID_PARAM | Invalid parameter (NULL pointer, bad length, unknown algorithm) |
| -2 | QUAC_ERR_DEVICE_NOT_FOUND | No QUAC 100 device at specified index |
| -3 | QUAC_ERR_DEVICE_BUSY | Device is in use by another process exclusively |
| -4 | QUAC_ERR_NOT_INITIALIZED | SDK not initialized (call quac_init first) |
| -5 | QUAC_ERR_BUFFER_TOO_SMALL | Output buffer insufficient (use *_output_size to query) |
| -6 | QUAC_ERR_VERIFY_FAILED | Signature verification failed |
| -7 | QUAC_ERR_KEY_NOT_FOUND | No key with the specified handle or label |
| -8 | QUAC_ERR_INVALID_STATE | Key lifecycle state does not permit this operation |
| -9 | QUAC_ERR_FIPS_NOT_APPROVED | Operation not permitted in FIPS mode |
| -10 | QUAC_ERR_QUEUE_FULL | Hardware command queue is full (async) |
| -11 | QUAC_ERR_TIMEOUT | Operation timed out |
| -12 | QUAC_ERR_IN_PROGRESS | Operation already executing (cannot cancel) |
| -13 | QUAC_ERR_HW_FAULT | Hardware fault detected (check tamper status) |
| -14 | QUAC_ERR_SELF_TEST_FAILED | POST or conditional self-test failed |
| -15 | QUAC_ERR_RNG_HEALTH | QRNG health test failure |
| -16 | QUAC_ERR_STORAGE_FULL | Key storage capacity exhausted |
| -17 | QUAC_ERR_PERMISSION | Insufficient permissions (driver, key usage) |
| -18 | QUAC_ERR_DRIVER | Kernel driver communication error |
| -19 | QUAC_ERR_FIRMWARE | Firmware error (check device logs) |
| -20 | QUAC_ERR_INTERNAL | Internal SDK error (bug — report to support) |
Next Steps #
For SDK packages and pre-built binaries, visit the Downloads page. For support tiers and licensing options, see Support & Licensing.
Was this page helpful? Send feedback