Lux GPU Core 0.2.0
Lightweight plugin-based GPU acceleration for blockchain and ML
Loading...
Searching...
No Matches
backend_plugin.h
Go to the documentation of this file.
1// Copyright (c) 2024-2026 Lux Industries Inc.
2// SPDX-License-Identifier: BSD-3-Clause-Eco
3//
4// Backend Plugin ABI - Stable C interface for runtime-loaded GPU backends
5//
6// Each backend shared library exports one symbol: lux_gpu_backend_init
7// The core library dlopen()s backends and calls this to get the vtable.
8//
9// One vtbl, one cross-backend contract. Each plugin is self-contained — there
10// is no parallel crypto vtbl, no extension struct. Crypto types live in
11// <lux/gpu/crypto.h>. The curve enum lives in <lux/gpu.h> as LuxCurve.
12
13#ifndef LUX_GPU_BACKEND_PLUGIN_H
14#define LUX_GPU_BACKEND_PLUGIN_H
15
16#include <stdint.h>
17#include <stddef.h>
18#include <stdbool.h>
19
20#include "lux/gpu/crypto.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26// =============================================================================
27// ABI Version - bump on breaking changes
28// =============================================================================
29
30// ABI v5: FHE ops take explicit base_log; k=0 and degenerate gadgets are
31// rejected with INVALID_ARGUMENT. CUDA/WGSL bootstrap+blind_rotate now run the
32// canonical CPU PBS body via cpu_fhe_helpers.hpp (no more rotation-only fakes).
33#define LUX_GPU_BACKEND_ABI_VERSION 5
34
35// =============================================================================
36// Forward declarations (opaque handles)
37// =============================================================================
38
41
42// =============================================================================
43// Error codes
44// =============================================================================
45
54
55typedef struct {
56 const char* name;
57 const char* vendor;
58 uint64_t memory_total;
65
66// =============================================================================
67// Backend vtbl — the single cross-backend contract.
68//
69// Layout: lifecycle -> device info -> sync -> buffers -> tensor ops ->
70// FHE/NTT -> crypto. No designated initializers required; missing trailing
71// fields are nullptr by virtue of static zero-init in the plugin.
72// =============================================================================
73
74typedef struct lux_gpu_backend_vtbl {
75 // -------- Lifecycle --------
76 LuxBackendContext* (*create_context)(int device_index);
78
79 // -------- Device info & sync --------
83
84 // -------- Buffer management --------
85 LuxBackendBuffer* (*buffer_alloc)(LuxBackendContext* ctx, size_t bytes);
86 LuxBackendBuffer* (*buffer_alloc_with_data)(LuxBackendContext* ctx, const void* data, size_t bytes);
89 LuxBackendError (*buffer_copy_from_host)(LuxBackendContext* ctx, LuxBackendBuffer* buf, const void* src, size_t bytes);
90 void* (*buffer_get_host_ptr)(LuxBackendContext* ctx, LuxBackendBuffer* buf);
91
92 // -------- Tensor ops (f32) --------
97
100
105 LuxBackendError (*op_reduce_sum_axis_f32)(LuxBackendContext* ctx, LuxBackendBuffer* in, LuxBackendBuffer* out, size_t outer_size, size_t inner_size);
106 LuxBackendError (*op_reduce_max_axis_f32)(LuxBackendContext* ctx, LuxBackendBuffer* in, LuxBackendBuffer* out, size_t outer_size, size_t inner_size);
107
108 LuxBackendError (*op_softmax_f32)(LuxBackendContext* ctx, LuxBackendBuffer* in, LuxBackendBuffer* out, size_t batch_size, size_t dim);
110
120
122
123 LuxBackendError (*op_layer_norm_f32)(LuxBackendContext* ctx, LuxBackendBuffer* in, LuxBackendBuffer* out, LuxBackendBuffer* gamma, LuxBackendBuffer* beta, size_t batch_size, size_t dim, float eps);
124 LuxBackendError (*op_rms_norm_f32)(LuxBackendContext* ctx, LuxBackendBuffer* in, LuxBackendBuffer* out, LuxBackendBuffer* weight, size_t batch_size, size_t dim, float eps);
125
126 // -------- NTT (host-pointer interface; backend manages staging) --------
127 LuxBackendError (*op_ntt_forward)(LuxBackendContext* ctx, uint64_t* data, size_t n, uint64_t modulus);
128 LuxBackendError (*op_ntt_inverse)(LuxBackendContext* ctx, uint64_t* data, size_t n, uint64_t modulus);
129
130 // -------- FHE (host-pointer interface; backend manages staging) --------
133 const uint64_t* a, const uint64_t* b, uint64_t* result,
134 size_t n, uint64_t modulus
135 );
136
137 // TFHE-AP programmable bootstrap. BSK layout per input LWE coordinate:
138 // [n_lwe][(k+1)*l][k+1][N] uint64_t (TRGSW row-major).
139 // Gadget contract: B = 2^base_log; the caller MUST choose (l, base_log)
140 // so that l × base_log ≤ log2(q). Otherwise q / B^l collapses to zero on
141 // the bottom row and that gadget level encrypts only noise. Backends
142 // reject l × base_log > 64 with INVALID_ARGUMENT.
143 // k = 0 is rejected: lwe_out length is documented as k*N + 1 = 1 yet the
144 // sample-extract writes N entries — silent OOB. INVALID_ARGUMENT instead.
147 const uint64_t* lwe_in, uint64_t* lwe_out,
148 const uint64_t* bsk, const uint64_t* test_poly,
149 uint32_t n_lwe, uint32_t N, uint32_t k, uint32_t l,
150 uint32_t base_log, uint64_t q
151 );
152
153 // TFHE keyswitch. KSK rows encode an LWE encryption (under the OUT key)
154 // of −s_{in_idx} · q / B^{level+1} where B = 2^base_log and
155 // s_{in_idx} is the IN secret-key coordinate. Accumulating
156 // +digit · KSK[in_idx][level] over the signed-base-B decomposition of
157 // lwe_in[in_idx] yields the keyswitched ciphertext under the OUT key.
158 // Callers MUST follow this convention.
161 const uint64_t* lwe_in, uint64_t* lwe_out,
162 const uint64_t* ksk,
163 uint32_t n_in, uint32_t n_out, uint32_t l, uint32_t base_log, uint64_t q
164 );
165
166 // AP-style blind rotation. Same gadget contract as op_tfhe_bootstrap.
169 uint64_t* acc, const uint64_t* bsk, const uint64_t* lwe_a,
170 uint32_t n_lwe, uint32_t N, uint32_t k, uint32_t l,
171 uint32_t base_log, uint64_t q
172 );
173
174 // -------- Crypto: hashes --------
177 const uint64_t* inputs, uint64_t* outputs,
178 size_t rate, size_t num_hashes
179 );
180
183 const uint8_t* inputs, uint8_t* outputs,
184 const size_t* input_lens, size_t num_hashes
185 );
186
189 const uint8_t* inputs, uint8_t* outputs,
190 const size_t* input_lens, size_t num_inputs
191 );
192
193 // -------- Crypto: BLS12-381 (G1 or G2 selected by is_g2) --------
196 const void* a, const void* b, void* out, size_t n, bool is_g2
197 );
200 const void* points, const void* scalars, void* out, size_t n, bool is_g2
201 );
204 const void* g1_points, const void* g2_points, void* out, size_t n
205 );
206
207 // -------- Crypto: BN254 (G1 or G2 selected by is_g2) --------
210 const void* a, const void* b, void* out, size_t n, bool is_g2
211 );
214 const void* points, const void* scalars, void* out, size_t n, bool is_g2
215 );
216
217 // -------- Crypto: MSM (curve_type is LuxCurve from <lux/gpu.h>) --------
220 const void* scalars, const void* points, void* result,
221 size_t n, int curve_type
222 );
223
224 // -------- Crypto: KZG polynomial commitments --------
227 const void* coeffs, const void* srs, void* commitment,
228 size_t degree, int curve_type
229 );
232 const void* coeffs, const void* srs, const void* point, void* proof,
233 size_t degree, int curve_type
234 );
237 const void* commitment, const void* proof,
238 const void* point, const void* value, const void* srs_g2,
239 bool* result, int curve_type
240 );
241
242 // -------- Crypto: secp256k1 ecrecover (Ethereum) --------
245 const void* signatures, void* addresses, size_t num_signatures
246 );
247
248 // -------- Crypto: Post-quantum signatures (FIPS 203/204/205) --------
249 //
250 // ML-DSA-65 (Dilithium3) batch verify. pubkeys: 1952B each, signatures:
251 // 3293B each (variable, padded to fixed stride by caller), messages:
252 // arbitrary pre-hashed digests (each entry is one msg with paired length).
253 // results[i] = true iff verification succeeded.
256 const uint8_t* const* pubkeys,
257 const uint8_t* const* messages,
258 const uint8_t* const* signatures,
259 bool* results,
260 size_t count
261 );
262
263 // ML-KEM-768 (Kyber768) batch decapsulation. secret_keys: 2400B each,
264 // ciphertexts: 1088B each, shared_secrets: 32B each (output).
267 const uint8_t* const* secret_keys,
268 const uint8_t* const* ciphertexts,
269 uint8_t** shared_secrets,
270 size_t count
271 );
272
273 // SLH-DSA (SPHINCS+) batch verify. SHA2-128f mode by convention: pubkeys
274 // 32B, sigs ~17088B. results[i] = true iff verification succeeded.
277 const uint8_t* const* pubkeys,
278 const uint8_t* const* messages,
279 const uint8_t* const* signatures,
280 bool* results,
281 size_t count
282 );
283
284 // -------- Crypto: Threshold signature primitives --------
285 //
286 // Ringtail lattice-based threshold: per-party partial signing pass.
287 // shares: 1024B each (per-party secret share), messages: 32B each,
288 // partial_sigs: 1024B each (output). Returns NOT_SUPPORTED on backends
289 // that do not implement the full ceremony pipeline.
292 const uint8_t* const* shares,
293 const uint8_t* const* messages,
294 uint8_t** partial_sigs,
295 size_t count
296 );
297
298 // Ringtail threshold combine: merge `threshold` partial sigs into one
299 // combined signature using Lagrange interpolation coefficients.
302 const uint8_t* const* partial_sigs,
303 const int32_t* lagrange_coeffs,
304 uint8_t** combined_sigs,
305 size_t threshold,
306 size_t count
307 );
308
309 // FROST threshold Schnorr partial-signature verification. commitments:
310 // 66B each, signatures: 32B each, pubkeys: 33B each, challenges: 32B
311 // each (pre-computed c*lambda_i scalars).
314 const uint8_t* const* commitments,
315 const uint8_t* const* signatures,
316 const uint8_t* const* pubkeys,
317 const uint8_t* const* challenges,
318 bool* results,
319 size_t count
320 );
321
322 // CGGMP21 threshold ECDSA partial-signing pass. Each entry packs:
323 // k_share[32] || chi_share[32] || msg_hash[32] || gamma_share[32].
324 // r_x is the x-coordinate of the combined nonce R shared across the
325 // batch. partial_sigs[i] is the per-party sigma_i (32B).
328 const uint8_t* const* inputs,
329 const uint8_t* r_x,
330 uint8_t** partial_sigs,
331 size_t count
332 );
333
334 // -------- Crypto: Classical Schnorr (Ed25519 / sr25519) --------
335 //
336 // Ed25519 (RFC 8032) batch verify. Messages are 64-byte digests by
337 // contract (host pre-hashes if larger; consumers must commit to a
338 // fixed-width input). pubkeys: 32B each, signatures: 64B each,
339 // results[i] = true iff verify(pk, msg, sig) succeeds.
342 const uint8_t* const* pubkeys,
343 const uint8_t* const* messages,
344 const uint8_t* const* signatures,
345 bool* results,
346 size_t count
347 );
348
349 // sr25519 (Schnorrkel/Ristretto255) batch verify. Same shape and
350 // 64-byte message contract as Ed25519, but uses the Substrate-style
351 // schnorrkel transcript.
354 const uint8_t* const* pubkeys,
355 const uint8_t* const* messages,
356 const uint8_t* const* signatures,
357 bool* results,
358 size_t count
359 );
361
362// =============================================================================
363// Backend Descriptor (returned by plugin init)
364//
365// vtbl_size is a hard-required cookie that lets the loader detect a plugin
366// that lies about its abi_version while shipping a truncated vtable. Each
367// plugin MUST set this to sizeof(lux_gpu_backend_vtbl) as compiled against
368// THIS header. The loader MUST reject any plugin whose vtbl_size does not
369// match the consumer's compile-time sizeof. This protects consumers from
370// reading past the end of an undersized vtable and dispatching through a
371// junk function pointer.
372// =============================================================================
373
374typedef struct {
375 uint32_t abi_version; // Must be LUX_GPU_BACKEND_ABI_VERSION
376 uint32_t vtbl_size; // Must equal sizeof(lux_gpu_backend_vtbl)
377 const char* backend_name; // "cpu" | "metal" | "cuda" | "webgpu"
378 const char* backend_version; // e.g., "0.1.0"
379 uint32_t capabilities; // Bitmask of supported features
382
383// =============================================================================
384// Capability flags (advisory, for feature gating in consumers)
385// =============================================================================
386
387#define LUX_CAP_TENSOR_OPS (1u << 0)
388#define LUX_CAP_MATMUL (1u << 1)
389#define LUX_CAP_NTT (1u << 2)
390#define LUX_CAP_MSM (1u << 3)
391#define LUX_CAP_UNIFIED_MEMORY (1u << 4)
392#define LUX_CAP_FHE (1u << 5)
393#define LUX_CAP_TFHE (1u << 6)
394#define LUX_CAP_REDUCE (1u << 7)
395#define LUX_CAP_SOFTMAX (1u << 8)
396#define LUX_CAP_UNARY (1u << 9)
397#define LUX_CAP_NORMALIZATION (1u << 10)
398#define LUX_CAP_BLS12_381 (1u << 11)
399#define LUX_CAP_BN254 (1u << 12)
400#define LUX_CAP_KZG (1u << 13)
401#define LUX_CAP_POSEIDON2 (1u << 14)
402#define LUX_CAP_BLAKE3 (1u << 15)
403#define LUX_CAP_KECCAK256 (1u << 16)
404#define LUX_CAP_ECRECOVER (1u << 17)
405#define LUX_CAP_BLIND_ROTATE (1u << 18)
406#define LUX_CAP_POLY_MUL (1u << 19)
407#define LUX_CAP_MLDSA (1u << 20)
408#define LUX_CAP_MLKEM (1u << 21)
409#define LUX_CAP_SLHDSA (1u << 22)
410#define LUX_CAP_RINGTAIL (1u << 23)
411#define LUX_CAP_FROST (1u << 24)
412#define LUX_CAP_CGGMP21 (1u << 25)
413#define LUX_CAP_ED25519 (1u << 26)
414#define LUX_CAP_SR25519 (1u << 27)
415
416// =============================================================================
417// Plugin Entry Point
418// =============================================================================
419
420// Every backend shared library must export this symbol.
421// Returns true on success, false if backend unavailable on this system.
423
424#define LUX_GPU_BACKEND_INIT_SYMBOL "lux_gpu_backend_init"
425
426#ifdef _WIN32
427#define LUX_GPU_BACKEND_EXPORT __declspec(dllexport)
428#else
429#define LUX_GPU_BACKEND_EXPORT __attribute__((visibility("default")))
430#endif
431
432#ifdef __cplusplus
433#define LUX_GPU_DECLARE_BACKEND(init_func) \
434 extern "C" LUX_GPU_BACKEND_EXPORT bool \
435 lux_gpu_backend_init(lux_gpu_backend_desc* out) { return init_func(out); }
436#else
437#define LUX_GPU_DECLARE_BACKEND(init_func) \
438 LUX_GPU_BACKEND_EXPORT bool \
439 lux_gpu_backend_init(lux_gpu_backend_desc* out) { return init_func(out); }
440#endif
441
442#ifdef __cplusplus
443}
444#endif
445
446#endif // LUX_GPU_BACKEND_PLUGIN_H
struct LuxBackendContext LuxBackendContext
bool(* lux_gpu_backend_init_fn)(lux_gpu_backend_desc *out)
LuxBackendError
@ LUX_BACKEND_ERROR_INTERNAL
@ LUX_BACKEND_ERROR_NOT_SUPPORTED
@ LUX_BACKEND_ERROR_DEVICE_LOST
@ LUX_BACKEND_OK
@ LUX_BACKEND_ERROR_INVALID_ARGUMENT
@ LUX_BACKEND_ERROR_OUT_OF_MEMORY
struct LuxBackendBuffer LuxBackendBuffer
const lux_gpu_backend_vtbl * vtbl
const char * backend_version
const char * backend_name
LuxBackendError(* op_kzg_verify)(LuxBackendContext *ctx, const void *commitment, const void *proof, const void *point, const void *value, const void *srs_g2, bool *result, int curve_type)
LuxBackendError(* op_sqrt_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_poly_mul)(LuxBackendContext *ctx, const uint64_t *a, const uint64_t *b, uint64_t *result, size_t n, uint64_t modulus)
LuxBackendError(* op_mldsa_verify_batch)(LuxBackendContext *ctx, const uint8_t *const *pubkeys, const uint8_t *const *messages, const uint8_t *const *signatures, bool *results, size_t count)
LuxBackendError(* op_neg_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_bls12_381_mul)(LuxBackendContext *ctx, const void *points, const void *scalars, void *out, size_t n, bool is_g2)
LuxBackendError(* op_reduce_sum_axis_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t outer_size, size_t inner_size)
LuxBackendError(* get_device_info)(LuxBackendContext *ctx, LuxBackendDeviceInfo *info)
LuxBackendError(* op_reduce_max_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_reduce_mean_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_abs_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_msm)(LuxBackendContext *ctx, const void *scalars, const void *points, void *result, size_t n, int curve_type)
LuxBackendError(* op_ecrecover_batch)(LuxBackendContext *ctx, const void *signatures, void *addresses, size_t num_signatures)
LuxBackendError(* op_mlkem_decapsulate_batch)(LuxBackendContext *ctx, const uint8_t *const *secret_keys, const uint8_t *const *ciphertexts, uint8_t **shared_secrets, size_t count)
LuxBackendError(* op_gelu_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_ntt_forward)(LuxBackendContext *ctx, uint64_t *data, size_t n, uint64_t modulus)
LuxBackendError(* op_sigmoid_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_log_softmax_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t batch_size, size_t dim)
LuxBackendError(* op_blind_rotate)(LuxBackendContext *ctx, uint64_t *acc, const uint64_t *bsk, const uint64_t *lwe_a, uint32_t n_lwe, uint32_t N, uint32_t k, uint32_t l, uint32_t base_log, uint64_t q)
LuxBackendError(* op_kzg_open)(LuxBackendContext *ctx, const void *coeffs, const void *srs, const void *point, void *proof, size_t degree, int curve_type)
LuxBackendError(* op_softmax_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t batch_size, size_t dim)
LuxBackendError(* op_ringtail_combine_batch)(LuxBackendContext *ctx, const uint8_t *const *partial_sigs, const int32_t *lagrange_coeffs, uint8_t **combined_sigs, size_t threshold, size_t count)
LuxBackendError(* op_tanh_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_cggmp21_partial_sign_batch)(LuxBackendContext *ctx, const uint8_t *const *inputs, const uint8_t *r_x, uint8_t **partial_sigs, size_t count)
LuxBackendError(* op_bls12_381_pairing)(LuxBackendContext *ctx, const void *g1_points, const void *g2_points, void *out, size_t n)
LuxBackendError(* op_reduce_max_axis_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t outer_size, size_t inner_size)
LuxBackendError(* op_ringtail_partial_sign_batch)(LuxBackendContext *ctx, const uint8_t *const *shares, const uint8_t *const *messages, uint8_t **partial_sigs, size_t count)
LuxBackendError(* op_kzg_commit)(LuxBackendContext *ctx, const void *coeffs, const void *srs, void *commitment, size_t degree, int curve_type)
void(* destroy_context)(LuxBackendContext *ctx)
LuxBackendError(* op_sub_f32)(LuxBackendContext *ctx, LuxBackendBuffer *a, LuxBackendBuffer *b, LuxBackendBuffer *out, size_t n)
LuxBackendError(* get_device_count)(int *count)
LuxBackendError(* op_copy_f32)(LuxBackendContext *ctx, LuxBackendBuffer *src, LuxBackendBuffer *dst, size_t n)
LuxBackendError(* op_exp_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_bls12_381_add)(LuxBackendContext *ctx, const void *a, const void *b, void *out, size_t n, bool is_g2)
LuxBackendError(* sync)(LuxBackendContext *ctx)
LuxBackendError(* op_slhdsa_verify_batch)(LuxBackendContext *ctx, const uint8_t *const *pubkeys, const uint8_t *const *messages, const uint8_t *const *signatures, bool *results, size_t count)
LuxBackendError(* op_blake3_hash)(LuxBackendContext *ctx, const uint8_t *inputs, uint8_t *outputs, const size_t *input_lens, size_t num_hashes)
LuxBackendError(* op_rms_norm_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, LuxBackendBuffer *weight, size_t batch_size, size_t dim, float eps)
LuxBackendError(* op_tfhe_bootstrap)(LuxBackendContext *ctx, const uint64_t *lwe_in, uint64_t *lwe_out, const uint64_t *bsk, const uint64_t *test_poly, uint32_t n_lwe, uint32_t N, uint32_t k, uint32_t l, uint32_t base_log, uint64_t q)
LuxBackendError(* op_layer_norm_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, LuxBackendBuffer *gamma, LuxBackendBuffer *beta, size_t batch_size, size_t dim, float eps)
LuxBackendError(* op_log_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_div_f32)(LuxBackendContext *ctx, LuxBackendBuffer *a, LuxBackendBuffer *b, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_matmul_f32)(LuxBackendContext *ctx, LuxBackendBuffer *a, LuxBackendBuffer *b, LuxBackendBuffer *out, int M, int K, int N)
LuxBackendError(* op_bn254_add)(LuxBackendContext *ctx, const void *a, const void *b, void *out, size_t n, bool is_g2)
LuxBackendError(* op_reduce_sum_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_keccak256_hash)(LuxBackendContext *ctx, const uint8_t *inputs, uint8_t *outputs, const size_t *input_lens, size_t num_inputs)
LuxBackendError(* op_ed25519_verify_batch)(LuxBackendContext *ctx, const uint8_t *const *pubkeys, const uint8_t *const *messages, const uint8_t *const *signatures, bool *results, size_t count)
LuxBackendError(* op_poseidon2_hash)(LuxBackendContext *ctx, const uint64_t *inputs, uint64_t *outputs, size_t rate, size_t num_hashes)
LuxBackendError(* op_add_f32)(LuxBackendContext *ctx, LuxBackendBuffer *a, LuxBackendBuffer *b, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_transpose_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, int rows, int cols)
LuxBackendError(* op_mul_f32)(LuxBackendContext *ctx, LuxBackendBuffer *a, LuxBackendBuffer *b, LuxBackendBuffer *out, size_t n)
LuxBackendError(* buffer_copy_from_host)(LuxBackendContext *ctx, LuxBackendBuffer *buf, const void *src, size_t bytes)
LuxBackendError(* op_relu_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_tfhe_keyswitch)(LuxBackendContext *ctx, const uint64_t *lwe_in, uint64_t *lwe_out, const uint64_t *ksk, uint32_t n_in, uint32_t n_out, uint32_t l, uint32_t base_log, uint64_t q)
void(* buffer_free)(LuxBackendContext *ctx, LuxBackendBuffer *buf)
LuxBackendError(* buffer_copy_to_host)(LuxBackendContext *ctx, LuxBackendBuffer *buf, void *dst, size_t bytes)
LuxBackendError(* op_reduce_min_f32)(LuxBackendContext *ctx, LuxBackendBuffer *in, LuxBackendBuffer *out, size_t n)
LuxBackendError(* op_bn254_mul)(LuxBackendContext *ctx, const void *points, const void *scalars, void *out, size_t n, bool is_g2)
LuxBackendError(* op_frost_partial_verify_batch)(LuxBackendContext *ctx, const uint8_t *const *commitments, const uint8_t *const *signatures, const uint8_t *const *pubkeys, const uint8_t *const *challenges, bool *results, size_t count)
LuxBackendError(* op_sr25519_verify_batch)(LuxBackendContext *ctx, const uint8_t *const *pubkeys, const uint8_t *const *messages, const uint8_t *const *signatures, bool *results, size_t count)
LuxBackendError(* op_ntt_inverse)(LuxBackendContext *ctx, uint64_t *data, size_t n, uint64_t modulus)