Status: experimental (v0.x), not independently audited. Do not put data you cannot afford to lose or leak into it yet. The cryptography has had internal reviews only, no external one.
FHEcolumns use BN254 (≈100-bit security, not 128), and the pure-Python pairing path is about 150× slower than the optional native one. The code, tests and docs were developed with substantial AI assistance (see Status and provenance). Known limits are listed indocs/threat-model.md.
The open developer surface of TorusDB — a SQL dialect, drivers and a keyless server for data that stays encrypted end to end.
You write ordinary-looking SQL. The server computes over blinded data and
never holds a key and never decrypts; results unblind only in your own
client. It runs the no-key delegation protocol (Lee, J1729 Labs): the server
sees a one-time pad of each encrypted value, so a breach of the server reveals
nothing about encrypted columns (I(M; V_S) = 0, unconditional).
┌──────────────── owner / client (trusted) ────────────────┐
│ driver · mask vault · blind / unblind · planner │
└──────────────────────────┬───────────────────────────────┘
blinded scalars │ Π_lin (affine) · Π_mult (Beaver)
┌──────────────────────────▼───── server (untrusted) ──────┐
│ NO keys · NO masks · NO decryption │
└───────────────────────────────────────────────────────────┘
New here? Start with docs/GETTING_STARTED.md (10 minutes,
install to a restart-safe encrypted SUM). Requires Python 3.11 or newer for the
Python packages, shell and server (python3 --version; macOS and older Linux often ship
3.9/3.10, and pip then fails with "requires a different Python").
Be precise about the guarantee. It covers the values of
ENC/PAIREDcolumns. The server still seesPLAINcolumns, the schema, row counts, access patterns and join keys, and — unless you enableauthenticated=True— can lie about results undetected. No independent cryptographic audit has been done (internal audit:docs/crypto-review-packet.md§11). Readdocs/threat-model.mdbefore relying on it.
CREATE TABLE emp (id INT PLAIN, dept INT PLAIN, salary RATIONAL ENC, rate INT PAIRED, hours INT PAIRED);
SELECT SUM(salary), AVG(salary) FROM emp WHERE dept = 5; -- encrypted aggregation
SELECT DOT(rate, hours) FROM emp; -- encrypted × encrypted (depth 1)
SELECT rate * hours * (rate - 10) + salary / 12 FROM emp; -- v0.6: + - * /, products of any depth
SELECT SUM(rate * hours) / COUNT(*) FROM emp; -- v0.6: aggregate of a product, then divide
SELECT rate / hours FROM emp; -- v0.6: division by an encrypted value (exact rational)
SELECT d.dname, COUNT(*), SUM(e.salary) -- joins + grouping + encrypted SUM
FROM emp e LEFT JOIN dept d ON e.dept = d.dept
GROUP BY d.dname HAVING COUNT(*) > 1 ORDER BY d.dname LIMIT 10;
SELECT e.name, m.name FROM emp e JOIN emp m ON e.mgr = m.id; -- self-join
UPDATE emp SET salary = FRAC(9500,1) WHERE id = 2; DELETE FROM emp WHERE dept = 9;INSERT/UPDATE/DELETE, SUM AVG MIN MAX COUNT, k*col, a*b, DOT, arithmetic expressions
+ - * / (products of arbitrary depth between PAIRED columns, SUM(a*b*c), division by public
and encrypted values — v0.6, see below),
WHERE (AND/OR/IN/NOT IN/BETWEEN/IS NULL/LIKE) on PLAIN columns, GROUP BY/HAVING, ORDER BY/LIMIT/DISTINCT,
aliases, INNER/LEFT joins (any number, self-joins), transactions. Full
reference and the list of what is not supported:
spec/TorusSQL-Spec-v0.6.md.
Expressions (v0.6) — who computes what. Every intermediate of an expression is a two-party
additive sharing over Z/nZ (the no-key paper's Π_C): the server keeps one share of each wire in a
session-scoped store, the owner keeps the other. Additions, subtractions, public scalar operations and
SUM are local to each party; a product of two encrypted wires is a Beaver exchange whose result
stays at the server as its share of a new wire; division by an encrypted value opens only
t = ρ·y for a fresh random non-zero ρ (uniform whatever y is — a zero denominator is replaced by a
dummy so even that is hidden) and never decrypts y. At the end the server sends its share of the result
and the owner adds its own and decodes. One request/response per multiplicative level (default
maximum 8, connect(..., max_mult_depth=N); a division by an encrypted value costs one extra level).
Honest accounting: the owner still does O(rows) ring arithmetic per level on its own shares (inherent
to unconditionally secure two-party computation — this mode is not faster than the old one) and, being the
dealer of the Beaver triples, is not cryptographically blind to operands and intermediates (the
openings determine them; the code never computes them) — only the server is, unconditionally. Without
authenticated=True the server is trusted to follow the protocol (a lying server can shift results and
test a denominator against a guess); with it every opening and the result are MAC-checked. Details:
spec §5.10, review packet §3.3 (findings F-18…F-25). The old owner-computed
transport remains as connect(..., expr_mode="owner") (works with any v2 server). x / 0 and out-of-range
results are errors, never wrong values. FHE columns keep depth-1 SUM/AVG/DOT, accept aggregated depth-1
products of integer-linear forms (SUM((a+2*b)*(c-d)), v0.6.1) and reject deeper products and division.
The TypeScript (db.expr(table, "SUM(a*b)/COUNT(*)")) and Rust (db.expr(...)) drivers evaluate the same expressions with the same grammar, results, errors and cost model, and use the same shared-wire transport by default (expressionMode: "owner" / ExprMode::Owner selects the old one; drivers/typescript/README.md, drivers/rust/README.md).
| Path | What |
|---|---|
spec/ |
Dialect specification + executable conformance suite |
parser/ |
torussql-parser — engine-free parser and static validator (zero deps) |
drivers/python/ |
torussql — PEP 249 driver (TLS, tokens, transactions, durable sealed vault, bulk load) |
drivers/typescript/, drivers/rust/ |
@torusdb/driver, torusdb — same protocol, joins, transactions, vault |
drivers/python/torussql/custody/ |
Threshold key custody (z-MPC-style Laurent sharing): dealerless DKG, k-of-n verifiable key use, refresh/reshare, custodian daemon, CLI — see docs/custody.md |
server/ |
torusdb-server — keyless server: auth/roles, WAL durability, backups, metrics, Docker |
proto/ |
Wire protocol v2 spec |
drivers/python/torussql/cli.py |
torussql — interactive shell (psql for TorusDB) |
docs/audit-scope.md |
Brief for an independent security reviewer |
docs/fhe-review-log.md |
Internal review findings of the FHE columns (fixed / residual) |
docs/fhe-columns.md |
FHE columns: server-side SUM/DOT on ciphertexts, no key at the server |
docs/ec-fhe-and-no-key.md |
Why the server never evaluates under a key |
docs/replication.md |
Hot standbys, promotion |
docs/storage.md |
Disk storage engine (--storage disk) and CREATE INDEX |
core/ |
torusdb-core — keyless engine: planner, blinding client, keyless store (Apache-2.0) |
bench/ |
Micro-, network and TPC-H-style benchmarks |
fuzz/, tests/ |
Fuzz/robustness and end-to-end suites |
docs/ |
Getting started, quickstart, ops guide, threat model, crypto review packet, versioning |
Everything here is Apache-2.0 and self-contained: no proprietary package is needed to build, run or test any of it.
The packages are not on PyPI yet; until they are, install from a checkout (run in the directory that contains this README, inside a Python >= 3.11 virtualenv):
python3.12 -m venv .venv && source .venv/bin/activate # any Python >= 3.11
pip install ./parser ./core ./drivers/python ./server # once published: pip install torusdb-server torussql
torusdb-server --db ./demo.db & # loopback; see docs/ops-guide.md for production
torussql --vault ./demo.vault # interactive shell, like psqltorussql> CREATE TABLE t (id INT PLAIN, v INT ENC);
torussql> INSERT INTO t (id, v) VALUES (1, 10);
torussql> INSERT INTO t (id, v) VALUES (2, 32);
torussql> SELECT SUM(v) FROM t; -- computed by the server on blinded data
or from code (use another table name, or another server/vault, if you already ran the shell
above: table 't' already exists):
import torussql
c = torussql.connect("127.0.0.1", 8533, vault_path="./demo.vault")
c.execute("CREATE TABLE t2 (id INT PLAIN, v INT ENC)")
c.cursor().executemany("INSERT INTO t2 (id, v) VALUES (%s, %s)", [(1, 10), (2, 32)])
print(c.execute("SELECT SUM(v) FROM t2").rows) # [[42]]Docker: docker build -f server/Dockerfile -t torusdb-server . (see the Dockerfile header).
FHE columns and threshold custody need an optional dependency: pip install "py_ecc>=6,<9"
(plus mclbn256 for native speed) — see docs/GETTING_STARTED.md §5.
The owner's mask vault can be sealed under a key that no one ever holds: it is
generated dealer-free by n custodians and used by any k of them through one
verifiable message each — the key is never reassembled (python -m torussql.custody,
docs/custody.md). Needs pip install "py_ecc>=6,<9" (extra torussql[custody]);
custodian hosts need neither the server nor the engine core.
- Disk storage (
--storage disk): data larger than RAM, crash-safe, auto-compacting —docs/storage.md - Indexes on plain columns:
CREATE INDEX ON t (col) - Replication: read-only hot standbys, promotion —
docs/replication.md - Snapshot reads: readers never block on another session's transaction
- Pooling / threads: thread-safe connections,
torussql.pool.ConnectionPool - Shell:
torussql(psql-like)
Durable (snapshot + WAL), authenticated (roles), TLS-verifying by default,
transactional, with backups, metrics, a disk storage engine, asynchronous/synchronous
replication with manual promotion and a hardened container image — see
docs/ops-guide.md, including a runbook and the honest list of
limitations (single writer node, no automatic fail-over, one open transaction at a time).
pip install pytest "py_ecc>=6,<9" # Python >= 3.11; the tests import the source tree directly
pytest # everything (pure Python; py_ecc for the FHE/custody tests)
pytest spec/conformance # just the dialect conformance suite
(cd drivers/typescript && npm ci && npm test) # Node >= 18
(cd drivers/rust && cargo test)- Maturity: v0.x, experimental. Measured in tests, not in production years: there is no long-running deployment, no large-scale load experience and no independent security audit.
- Security review so far: internal and AI-assisted review rounds with proof-of-concept
attacks, every confirmed finding fixed and covered by a regression test
(
docs/fhe-review-log.md). That is not a substitute for an external audit; a brief for one is indocs/audit-scope.md. - How it was built: the author designed the protocols and the product; the implementation, tests and documentation were produced with substantial help from AI coding assistants and reviewed by running the test suites and attack scripts, not by line-by-line human review of every file. Treat the code accordingly and read it before you rely on it.
- Not in this repository: the EC-FHE engine used by the full TorusDB product is closed source; this repository is the key-less server layer, drivers and spec, and works without it.
TorusDB is developed in the open and is not funded by a product company. Donations go to:
- an independent cryptographic audit of the
FHEcolumns and the key-less protocol (seedocs/audit-scope.md), - maintenance: CI, releases, security fixes, documentation.
Sponsor via the Sponsor button on the repository page. Funding is support for the work, not a security guarantee or a support contract, and sponsors get no special access to vulnerability reports.
Questions and ideas: Discussions · Help: SUPPORT.md · Conduct: CODE_OF_CONDUCT.md
Contributing: CONTRIBUTING.md · Security reports:
SECURITY.md · Changes: CHANGELOG.md · Plan:
ROADMAP.md · License: Apache-2.0 (LICENSE).
