How-To: Run an Encrypted Query
This guide shows how to send an input to a model without revealing it: the query client encrypts it, the model runs on the ciphertext, and the client decrypts the result. Examples are in Python and TypeScript.
What happens in a query
- Your machineEncryptYour input is encrypted with your secret key, on your machine.Sends: the encrypted input
- Lattica workerExecuteThe worker runs the model on the ciphertext, using your evaluation key. It never sees your data.Returns: the encrypted result
- Your machineDecryptThe result is decrypted with your secret key, on your machine.
Before you start
The token's evaluation key must be uploaded. See Upload Evaluation Key.
The model needs a running worker to process queries.
The User Access Token must be Active and assigned to the model.
Run the query
- Python
- TypeScript
In Python, client.query.encrypted does all three stages in one call and returns the decrypted result as a tensor. The Python SDK has no separate public calls for encrypting, executing or decrypting.
import os
import torch
from lattica_query import QueryClient, QueryToken
token = QueryToken(os.environ["LATTICA_QUERY_TOKEN"])
pt = torch.rand(1, 28, 28) # your input, shaped as the model expects
with QueryClient(token) as client:
key = client.keys.ensure()
# Encrypt locally, execute on the worker, decrypt locally.
result = client.query.encrypted(pt, key=key)
print(result)
Call client.query.encrypted again with each new input. The key is reused.
The TypeScript client exposes each stage as its own call:
import { initWasm, LatticaQueryClient, vecToTensor } from '@lattica-ai/query';
await initWasm();
const client = new LatticaQueryClient(process.env.LATTICA_QUERY_TOKEN!);
await client.init(); // keys: see Upload Evaluation Key
const pt = vecToTensor([0.12, 0.5, 0.33, 0.9]); // your input, shaped as the model expects
// 1. Encrypt: locally, with your secret key.
const encryptedInput = await client.encrypt(pt);
// 2. Execute: the worker runs the model on the ciphertext.
const encryptedResult = await client.apply_query(encryptedInput);
// 3. Decrypt: locally, with your secret key.
const result = await client.decrypt(encryptedResult);
Or run all three stages in one call with runQuery:
const result = await client.runQuery(pt);
A running worker uses credits even when idle. When you've finished querying, stop the worker.