Software

The software is open. The API is two files.

Everything host-side is open source and on our GitLab: the kernel driver (GPL-2.0), the demos, the test rigs, and a virtual card. The interface they all present is deliberately tiny — and frozen.

The interface is a file

No SDK, no vendor library, no ioctls — you talk to Blitz through file descriptors. The first is the verification stream, /dev/blitz/verify0: a signature check is a 160-byte record — five curve values, 32 bytes each — and a verdict is one byte. write() requests, read() verdicts, in order; batching is just longer writes. Open it from as many processes as you like — the kernel driver does the heavy lifting, tagging every request and routing each verdict back to the process that asked; you just read and write. The record format is a frozen ABI (verify_abi.h): code you write today keeps working.

Listing 1 sigcheck_demo.py — write a record, read a verdict
import os

VERDICT = {0: "FAIL", 1: "PASS", 2: "UNKNOWN"}

def record(pub, r, s, e):
    """px | py | r | s | e — 32 bytes each, little-endian."""
    return b"".join(v.to_bytes(32, "little") for v in (*pub, r, s, e))

fd = os.open("/dev/blitz/verify0", os.O_RDWR)

os.write(fd, record(pub, r, s, e))
print(VERDICT[os.read(fd, 1)[0]])         # PASS

os.write(fd, record(pub, r, s ^ 1, e))    # flip one bit of s
print(VERDICT[os.read(fd, 1)[0]])         # FAIL

Condensed from the runnable demo — full version on GitLab →

Verdicts are ternary. That's a safety feature.

The card never answers in binary. A verdict is PASS, FAIL, or UNKNOWN — and every failure of the machinery itself (a timeout, a dropped response, an integrity-checksum mismatch) is delivered as UNKNOWN, structurally distinct from a cryptographic verdict. The hardware can stall, the cable can be pulled mid-batch, and the one thing that cannot happen is a transport problem dressed up as a PASS or a FAIL.

That is what makes the card fit for consensus-critical software: an UNKNOWN is an instruction to fall back and re-check in software, never a signal to accept or reject a signature.

The second file: everything else on the card

Everything that isn't the stream — identity and versions, temperature and power, the on-card FRAM, the flash update windows — is /dev/blitz/mem0: the card's register map as a file, pread()/pwrite() at offset = register address. The guard rails live in the driver, not in your code — nothing you can write through this handle can brick the card. And the two files are just the first two: this is the platform's driver, so a future core — whatever it computes — arrives as a driver upgrade and a new file descriptor, never a new stack.

And you don't need a header file — or an import blitz — to know the addresses: the register map ships on the card, as plain JSON in a fixed flash sector beside the bitstream, CRC-protected and version-paired with the running image. Any language that can read bytes at an offset gets every register by name, with no library between you and the hardware. The artifact chain is generated straight from the ABI document and already proven on silicon.

Listing 2 map_demo.py — registers by name, straight off the flash
import json, os, struct, zlib

fd   = os.open("/dev/blitz/mem0", os.O_RDWR)
reg  = lambda addr: int.from_bytes(os.pread(fd, 4, addr), "little")
base = 0x1000_0000 + reg(0x0034)    # flash window + app-slot base

hdr = os.pread(fd, 16, base)        # magic | length | CRC32 | version
magic, length, crc, ver = struct.unpack("<4sIII", hdr)
data = os.pread(fd, length, base + 16)
assert magic == b"BRM1" and zlib.crc32(data) == crc

regs = json.loads(data)["regs"]     # {"STATUS": 32, "TEMP": 64, ...}
print(reg(regs["STATUS"]))          # 1 -- by name, no library

The full contract — MEM-ABI.md (publishes with the platform repo)

The GUI uses the same two files

There is no SDK and no client library to learn — the two files are the whole interface. The Blitz GUI is the proof: it is powered by a small open-source Python daemon (MIT) that owns the card by reading and writing the same /dev/blitz file descriptors you would, and the GUI is just a window onto it. Everything it shows, you can read yourself with pread() on /dev/blitz/mem0 — same files, same addresses, no privileged path. The daemon on GitLab →

And it's not a mockup — the live view streaming from the bench is that GUI, on a real card, right now. Live from the bench →

The virtual card: design against Blitz without a Blitz

vblitz is a small open-source daemon that creates a literal /dev/vblitz/verify0 — the same frozen ABI, implemented in software, with no hardware and no kernel module. Applications written against the real card run unmodified against it: same bytes, same errnos, swap onto silicon by changing nothing but the device path. Its verdicts come from libsecp256k1's arithmetic core, and they are cross-checked byte-for-byte against real silicon on a shared adversarial corpus.

That makes it the design surface: write your integration on a laptop, run it in CI on any Linux box, replay adversarial corpora — and none of it needs a card in the machine.

Tested like the hardware it drives

The muxer — the part of the kernel driver that must never lose or misroute a verdict — is deliberately written without kernel dependencies, so the same object file that ships inside the kernel module is proven in three card-free rigs before it ever touches silicon.

Userspace battery

Unit tests with address sanitizers and fault injection — drops, corruption, adversarial timing — in about two seconds per run.

Cosimulation

The same muxer linked against the real transport RTL under Verilator — the actual hardware design, simulated cycle by cycle, no card required.

In-kernel dummy card

The full kernel module loaded against a simulated card with fault knobs, so ABI conformance and multi-process stress run on any Linux box.

Then silicon: 1.8 million-plus checks against the software reference across concurrent processes — zero strays, zero mismatches (Ti375 devkit · 2026-07-17). The first multi-process silicon run found two real driver bugs; both fixes are in-tree with their war stories in the repo's journal.

Read it, build it, run it

Driver source, runnable demos, the test rigs, and the virtual card are all public. No account, no NDA — git clone and go.