Skip to main content
How-To · Secure Query Processing

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​

  1. Your machineEncryptYour input is encrypted with your secret key, on your machine.Sends: the encrypted input
  2. Lattica workerExecuteThe worker runs the model on the ciphertext, using your evaluation key. It never sees your data.Returns: the encrypted result
  3. Your machineDecryptThe result is decrypted with your secret key, on your machine.
Only ciphertext leaves your machine. Your input, the result and your secret key stay with you.

Before you start​

Your key is uploaded

The token's evaluation key must be uploaded. See Upload Evaluation Key.

A worker is running

The model needs a running worker to process queries.

Active token

The User Access Token must be Active and assigned to the model.

Run the query​

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.

query.py
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.

A running worker uses credits even when idle. When you've finished querying, stop the worker.