Architecture
zkFMI separates three jobs that conventional infrastructure fuses: deciding a trade, instructing its settlement, and settling it. Each job runs in a component that holds only the secrets that job needs. The joints between them are commitments, proofs and signatures, never plaintext.
The shape of the system
Three words are used precisely on this site. An instruction source is anything that decides a transfer and issues a zkPI. A venue is an instruction source that decides by matching many parties' orders or quotes (QOMM, OCLOB). An application is an instruction source that decides by its own business rules (a fund administrator, a collateral engine, a bank's checks, Aethel). The settlement layer cannot tell them apart, which is the point.
flowchart LR
subgraph up["instruction sources: decide"]
Q["QOMM
oblivious RFQ"]
O["OCLOB
oblivious order book"]
A["Aethel
receivables"]
X["any business system
fund, collateral, bank"]
end
subgraph gate["eligibility"]
K["DeKYX
anonymous qualification"]
end
subgraph inst["instructs"]
Z["zkPI
committed instruction
+ quorum signature
+ range proofs"]
end
subgraph clear["clears (optional)"]
C["DeCCP
netting, margin, waterfall"]
end
subgraph settle["settles"]
D["DeFMI
notes, asset tags,
DvP / PvP, reconciliation"]
L["Avalanche L1
5 validators, Rust VM"]
D --- L
end
K -.->|"verified eligibility"| Q
K -.->|"verified eligibility"| O
K -.->|"verified eligibility"| C
Q --> Z
O --> Z
A --> Z
X --> Z
Z --> C --> D
Z --> D
D -->|"receipt, state root"| up
classDef secret stroke:#f2b880,stroke-width:2px
classDef mech stroke:#9bb0ff,stroke-width:2px
classDef ok stroke:#5ee0c1,stroke-width:2px
class Q,O,A,X secret
class Z,K,C mech
class D,L ok
Three properties follow from that shape and are worth holding onto while reading the rest of the site.
- The settlement layer has no opinion about meaning. DeFMI checks arithmetic: conservation, non-negativity, the product relation, atomicity, single use. Whether the price was reasonable or the instrument was the right one is the instruction source's decision and travels in the quorum signature. Making DeFMI re-derive it would mean handing it the plaintext, which is the one thing the construction exists to avoid.
- The instruction is the only thing that crosses. The request, the pricing policies and the losing quotes never leave the instruction source. What the venue publishes is a committed instruction, a nullifier, a deadline and a signature.
- Every instruction source is replaceable. QOMM was built first, but a fund administrator, a collateral engine or a bank's sanctions check can issue the same instruction type. The applications page orders those by feasibility.
One settlement, end to end
Two instruction sources are traced. The first is the RFQ venue, because it is the most complete path built so far and exercises every proof. The second is a fund administrator, which has no MPC and no auction and reaches the same settlement layer with the same instruction type; the applications page ranks it as the first product. OCLOB replaces the pricing step of the first with matching; everything from the instruction onward is shared.
Through the RFQ venue
sequenceDiagram
autonumber
participant T as Taker
participant N as 7 MPC nodes
participant M as Makers (policies dealt in advance)
participant Q as 3-of-7 quorum
participant V as DeFMI validators (5)
T->>N: additive shares of (asset, size, side), fixed cadence
M-->>N: committed pricing rules, dealt as Shamir shares
N->>N: price every maker, gate eligibility, binary tournament
N->>N: open one key: winner and committed price
N->>N: quote proof: winner is the minimum of committed keys
N->>Q: assemble two threshold range proofs (amount, price)
Q->>Q: FROST-sign the instruction (nonce, deadline, digest)
Q->>V: zkPI + complete quote proof + DvP package
V->>V: verify approval, instruction, proofs, price limit, asset link, roots, nullifier
V->>V: apply both legs atomically, or neither
V-->>T: height, receipt, state root before and after
Through a fund administrator
sequenceDiagram
autonumber
participant I as Investor
participant K as KYC provider (DeKYX)
participant F as Fund administrator
participant Q as Issuing quorum
participant V as DeFMI validators
I->>K: prove eligibility for this fund (scope, cap, expiry)
K-->>F: verified eligibility, subject line only
I->>F: subscription request, cash reserved as a committed note
F->>F: check cap, units available, NAV point
F->>Q: decision as a typed instruction: cash leg, unit leg, deadline, nonce
Q->>V: zkPI with range proofs and quorum signature
V->>V: verify, then issue units and move cash atomically, or neither
V-->>I: receipt and state root
Nothing in the settlement layer knows whether the instruction came from an auction or a subscription form. The shared crate boundaries below preserve that separation.
Who holds which secret
| Secret | Held by | Seen by settlement? | Mechanism |
|---|---|---|---|
| the request (asset, size, side) | taker; nodes hold shares | no | additive shares over relay hops, fixed cadence so the trace is the same whether or not anyone asked |
| a maker's pricing rule | maker; nodes hold shares | no | committed, dealt with signed shares; the commitment is what the audit is stated against |
| the losing quotes | nobody after the tournament | no | only one key is opened |
| the winning price | nobody in the clear | no | Pedersen commitment carried through proof, signature, instruction and ledger |
| amount, quantity | counterparties | no | commitments, range proofs, product proof |
| which instrument | counterparties | no | blinded asset tag; membership proved once at issue |
| who paid whom | counterparties | no | note ledger, Groth–Kohlweiss one-of-many ring; per-venue handles |
| who is eligible | DeKYX issuer and holder | only a scoped subject line | anonymous presentation bound to audience, action, nonce, expiry |
| the audit view | a named auditor, one scope | — | scoped view keys derived per instrument or period; incoming notes only, no spend capability |
Repositories and crates
Eight repositories, one owner per crate. Since 2026-09-08, shared proofs and committee services are separate from QOMM-only modules. The table uses the actual package names. Dependencies remain acyclic: zkfmi-crypto ← zkpi ← defmi ← qomm; OCLOB and Aethel also use the shared layers, without depending on QOMM. Repository dependencies are pinned by immutable Git revision.
| Repository | Role | Principal crates, by layer | Depends on |
|---|---|---|---|
| zkpi | instruction, shared proofs, committee services, MPC engine | zkfmi-zk, zkpi, zkpi-proofs, zkpi-committee, zkpi-harness, zkfmi-measure, qomm-dsl, qomm-sim, qomm-mpc, qomm-audit; standalone qomm-batch-audit | zkfmi-crypto, curve25519-dalek, bulletproofs, frost-ristretto255, MP-SPDZ (external) |
| defmi | settlement ledger and Avalanche VM | defmi, defmi-avalanche-vm, zkpi-defmi-sdk, defmi-harness | zkpi, dekyx |
| qomm | oblivious RFQ venue | qomm-law, qomm-proofs, qomm-transport, qomm-demo, qomm-harness | zkfmi-crypto, zkpi, defmi, deccp-core, dekyx-core |
| oclob | oblivious order book | oclob-core, oclob-edge, oclob-node, oclob-ordering, oclob-mpc, oclob-settlement | zkfmi-crypto, dekyx, zkPI/DeFMI SDK, MP-SPDZ |
| dekyx | eligibility credentials | dekyx-core | zkfmi-crypto (ports only otherwise) |
| deccp | clearing state machine | deccp-core | zkfmi-crypto (ports only otherwise) |
| aethel | receivables | aethel-core and eleven siblings, including the aethel-deccp, aethel-dekyx, aethel-zkpi and aethel-defmi-host adapters | zkfmi-crypto, zkpi, defmi, dekyx, deccp |
| zkfmi-crypto | shared primitives and the post-quantum migration | zkfmi-crypto (single package) | none |
zkpi-proofs retains threshold and quote proofs used by settlement; zkpi-committee retains proof services, authorization, recipient encryption and durable execution. QOMM owns rule, policy, state and liquidity audits plus venue ingress and deployment adapters. The remaining qomm- prefixes in zkPI are historical. The defmi-avalanche-vm package still produces the qomm-avalanche-vm binary expected by the launch scripts.
Cryptographic primitives, used not rewritten
Everything sits on ristretto255. Audited crates supply the curve, the range proofs and the threshold signature; the project's own gadgets are sigma protocols over them.
flowchart TB
subgraph ext["audited crates"]
DALEK["curve25519-dalek
ristretto255"]
BP["bulletproofs
range proofs"]
FROST["frost-ristretto255
threshold signatures"]
end
subgraph zk["zero-knowledge gadgets"]
PED["pedersen
commitments, asset tags"]
SIG["sigma
opening, cross-generator, product"]
RNG["range"]
OOM["oneofmany
Groth-Kohlweiss"]
ORD["or_dleq"]
ADP["adaptor
pre-sign, adapt, extract"]
SHA["shamir
Reed-Solomon decoder"]
end
subgraph pi["instruction crate"]
ISS["issuer
KYB credentials"]
INS["instruction
commit, bound, nullify"]
QUO["quorum"]
HAN["handles
one seed, an unrelated point per venue"]
end
DALEK --> PED
DALEK --> HAN
BP --> RNG
FROST --> QUO
PED --> SIG
PED --> OOM
PED --> ORD
SIG --> ADP
SIG --> INS
RNG --> INS
OOM --> ISS
ORD --> ISS
INS --> QUO
HAN --> INS
The field is matched deliberately: the MPC runs over the same prime as the commitment group's order, so a commitment to a share is a linear statement the auditor can replay. That match is what makes auditability cost 2.00× traffic and nothing else, and it is also what keeps the stack on discrete-log assumptions rather than lattices. The prior-art page explains why both halves of that trade are true.
Execution target
The deployed path is a dedicated non-EVM Avalanche L1. AvalancheGo is an external consensus host that launches the Rust VM over RPCChainVM protocol 45. The VM has native transitions for asset registration, account opening, pre-authorised reserves and atomic multi-leg settlement. No Solidity, no EVM bytecode, no precompile is in the acceptance path.
The reasons EVM and Solana were rejected are recorded rather than assumed: one ed25519 scalar multiplication in EVM bytecode measured 302,401 gas, and on Solana the Groth–Kohlweiss verifier's scalar-field polynomial evaluation exceeds the compute ceiling at a crowd of 64 because the runtime has curve syscalls but no field syscalls. The zkPI page has the table.