I'm a Nuclear Engineer turned Software Engineer. I'm passionate about learning and sharing my knowledge with others. I'm currently working on a few projects and I'm always looking for new opportunities to learn and grow.
Series finale. Shor's algorithm breaks every elliptic-curve assumption F_RP currently rests on. The migration: lattice polynomial commitments (Brakedown/Orion), hash-based STARKs as universal backend, isogeny group actions for credentials.
Poseidon-128 over BN254 has converged on a small number of canonical parameter sets, but the round-constant tables shipped by widely deployed implementations diverge subtly. We document the methodology by which a production parameter set should be selected — the Grain-LFSR procedure of Grassi et al., the security margin, and the alpha-vs-round-count tradeoff for BN254. We trace the divergence…
Two of the big three quietly raised egress this quarter while announcing "AI-friendly" pricing on inbound. Storage is cheap, compute is cheap, the bill is the door. Pick your stack assuming you'll have to evacuate it under load. Anyone telling you "the data lives where the GPUs live" is selling you a one-way ticket.
We formalise the choice of locating the nullifier set in consensus state, rather than in wallet-side software, for a UTXO-based privacy chain derived from Bitcoin. We give a chain model extending the Bitcoin backbone protocol with a shielded UTXO type, a soundness theorem bounding the probability of an accepted double-spend by the collision probability of the underlying nullifier hash, and a proof…
We argue that SDKs exposing cryptographic primitives to autonomous AI agents must obey an explicit asymmetry rule: read and pure-compute operations may be exposed without privilege, but state-changing authority must remain behind an out-of-band human or hardware confirmation. We formalise this rule, instantiate it for a shielded-pool zero-knowledge SDK exposing its surface via the Model Context…
Threw a live-crowd HUD on the pike_pupday site. Polls a /api/count every 10s, animates the integer with framer-motion. Konami code on the page swaps in a different overlay (yes, it's a leather-bar event site — what did you expect). The thing I'm proudest of is the not-dead-when-API-is-down fallback. If the API hasn't returned a number in 60s, the HUD fades to grey and shows "—" instead of…
Added CompressedTokenHelper.compress(...) and .decompress(...) to the z_trade SDK. Light Protocol's ZK Compression charges roughly $0.000004 per compressed account vs $0.002 for a regular SPL token account — a 500× cost reduction once you're moving more than a few hundred accounts. The helper does the boring CPI plumbing: wrap-and-decompose the user's instruction, route through the Light System…
A user reported they couldn't sell tokens that had graduated from the launchpad to the open AMM. Swap quote returned valid, swap submit returned 0x1771 — slippage exceeded. Except slippage tolerance was 50%. Real cause: the bonding curve's migrate_authority had handed liquidity to the AMM, but our frontend was still pulling quotes from the bonding-curve route. Fixed by checking the migration flag…
Shipped the macOS sidecar bundling pass for vanta-desktop. The setup-sidecars.sh script now copies the right Rust frameworks into Frameworks/ so notarization stops failing on missing dylibs. v2 test renames so vanta_v2_*.rs reads consistently with the vanta-node-v2 rust crate name. The thing nobody tells you about Tauri 2.x sidecars: the binary name in tauri.conf.json must match the target triple…
F_RP vs nine deployed privacy systems on the four axes that matter: relayer-free, Turing-complete, on-chain verifiable on a high-perf L1, low-trust setup.
Shipped the btc-tunnel.sh family for vanta-desktop. Two parts: an SSH local-forward to a remote bitcoind 's RPC port, and an address-watcher loop that polls for confirmations on a set of P2WPKH addresses without exposing your local node. Pattern that's saved me twice now: never run bitcoind on 0.0.0.0:8332 . Always bind to 127.0.0.1:8332 and SSH-forward. The number of testnet bitcoinds I've seen…
Spent yesterday writing the price-discovery design for vanta-swap . The interesting part isn't the HTLC primitive — that's been solved since BIP-199 — it's the price oracle problem when both legs are private. If neither side reveals the amount, who arbitrates the rate? Three options: pre-committed price ranges (boring), threshold-decrypter set (works but adds trust), or a verifiable shuffle over a…
The explorer used to render ZK transfers as "unknown opcode" because the parser was Bitcoin-Core-flavoured and didn't speak our witness-v2. Refactored to detect the privacy opcode prefix early in the decoder, then route to a dedicated renderer that shows nullifiers, commitments, and proof byte length without ever trying to interpret the encrypted note ciphertext. Genesis scan was the surprise win:…
The explorer was running as two separate Fly machines: one Node API at :3000 , one nginx-served SPA at :80 . Doubled the rent, doubled the surface area. Consolidated into a single Express handler that serves the SPA on / and the JSON API on /api/* . The thing nobody tells you: Fly's free tier is metered per machine , not per port . A 2-machine setup of two 256MB VMs is twice the cost of one 512MB…
For users on phones or low-end laptops, generating a Groth16 proof in 1.5s is still 1.5s of dead UI. Added a /prove endpoint on vanta-explorer that takes a witness, runs the prover server-side, and returns the 128-byte proof. Trust trade-off documented in the desktop app — server sees the witness, but only the user sees the resulting note keys. Same commit fixes the Linux WebKit build for…
Bitcoin uses COINBASE_MATURITY=100 (you can't spend a coinbase output until 100 blocks deep). With our 1-minute target block time, that's 100 minutes of waiting before mining rewards become spendable. Cut to 30 for a smoother dev/UX experience. Still safe — the reorg history on Vanta is dominated by 1-deep reorgs. Bigger fix in the same commit: the L2 /submit endpoint was mutating the sparse…
x402 amounts travel as JSON strings. "1000", "1e3", " 1000 ", "+1000", "01000" round-trip differently across implementations. Any disagreement between the facilitator's validator and Solana's transfer is monetisable.
Stood up the SDK devnet docs + quickstart guide. The shielded-pool program ID had a stale value in the SDK's default config — three minutes of "why does my proof verify but the CPI fails" before I noticed. Hardcoded constant in crates/zera-sdk-rs/src/constants.rs was pointing at the old program; now derived from ZERA_NETWORK env so devnet/mainnet stay separate by construction. Tip if you're ever…
Concrete F_RP instantiation on Solana. Groth16 over BN254, Poseidon Merkle, indexed nullifier tree, BN254 Pedersen, transaction in 656 of 1,232 bytes, 235K of 1.4M CU.
Found a fun chain-init bug. The ZK proof verification path was being triggered on every block from genesis, but the first ~1000 blocks were minted before the shielded-pool program was deployed. The verifier kept trying to read a commitment tree that didn't exist; transactions silently dropped. Fix: hardcode ZK_ACTIVATION_HEIGHT = 997 so blocks 0..996 skip ZK verification entirely…
Subtle wallet UX win: when a user has both a 5 BTC note and three 1.66 BTC notes, the wallet would pick whichever combo summed closest to the target output. That's optimal for change minimisation — but proof generation time scales linearly with input notes, and a 1-input proof is 3-5× faster than a 3-input one on the same hardware. New rule: prefer the smallest set of notes that sum to ≥ target,…
Vite 5 with "type": "module" rejects require("crypto") . Symptom: dev server boots, prod build silently drops the crypto import, runtime crashes on first signature verify. No warning at build time. Fix: import { createHash } from "node:crypto" (the node: prefix matters too — without it, the bundler tries to find a polyfill called "crypto" and ships ~120KB of extra code). The node: prefix tells…
Two features in one commit: Auto-shield mining rewards — when a Vanta block matures (30 confirmations), the wallet automatically converts the coinbase into a shielded note. No manual shield 6.25 step. The miner who runs the wallet is now indistinguishable on-chain from any other shielded participant. Atomic-swap CLI — zer-cli swap btc:0.001 zer:200 opens an HTLC against a remote counterparty,…
ZL1 seed-node deploy lands. Dockerfile is a tiny multi-stage Rust build; fly.toml declares 1 GB memory + persistent volume for the chain database + restart policy on-failure . Three Fly gotchas I keep tripping over: (1) min_machines_running = 1 is not the default, and seed nodes need it on; (2) auto_stop_machines = false for the same reason — Fly's eager scale-to-zero will kill your peer; (3)…
Hit 144 tests across the zera-sdk monorepo today. Coverage is decent on note , commitment , nullifier , and the Groth16 verifier glue; thinner on the Solana-side CPI dispatch, which is where the integration matrix is going to be painful. The shape of the test pyramid is wrong: too many unit tests, not enough end-to-end. Need a bun test:e2e lane that boots a local solana-test-validator + deploys…
Wallet v3 has the Groth16 proving core wired in, plus a real data layer (no more localStorage mocks). Note scanning runs against the actual nullifier tree, wallet unlock derives keys from a passphrase via Argon2id. The bit that took the longest wasn't the proving — that's a wasm import — it was the note discovery . Every block, the wallet has to try-decrypt every commitment to see which ones are…
AI agents on x402 use programmatic keypairs and auto-approve every payment under a price threshold. A service that ramps prices upward slowly after trust is established drains the agent without ever tripping the threshold.
Data dominates. If you've chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming. — Rob Pike I keep coming back to this every time I'm tempted to be clever in a hot path. Nine times out of ten the win was upstream: a different shape, a different index, a different lifetime. The…
Pushed the SOLMAL writeup with confirmed proofs-of-concept against the x402 (HTTP 402 micropayment) protocol. Three issues found, all in the handshake between agent and merchant — the protocol assumes the merchant's response is unforgeable, which is true if you trust the network layer but isn't if anyone can MITM the agent's outbound request. PoCs land on a mock merchant + mock agent; mitigations…
F_RP Construction IV. The five-algorithm tuple Setup/Deploy/Invoke/Verify/Finalize plus the simulation-based privacy theorem (3.12) and self-sovereignty theorem (3.13). The composition that makes the whole thing deployable.
cruiser Phase 30 lands: a master gossip topic that all nodes join on first boot, plus a small set of seed nodes pinned in the binary. Once you've heard one peer through the master topic, you can drop into per-app sub-topics and never speak to the master again. Trade-off: the master topic centralises discovery (everyone hits it once), but at least it's not a TLS-terminating tracker — just an…
Spent an hour fighting Xcode Cloud CI for the Cruiser+ iOS build. The runner has Xcode and Homebrew but does not have Rust, Node, or pnpm preinstalled — and the default ci_post_clone.sh doesn't get them. Fixed with a tiny shell script that installs all three from scratch on every cold start (~90s overhead, acceptable). Lesson: Xcode Cloud is fine for pure-Swift projects. For anything Tauri / iroh…
Three commits in 5 minutes: 4e67803 rename bundle ID to com.cruiserplus.app 1cc74bd rename bundle ID to com.cruisergay.app , fix RGBA icons 2eed5f8 fix Cruiser+ name in Xcode project Lesson: Apple's review process treats cruiserplus and cruisergay very differently. The first review came back asking us to "clarify the app's audience"; the second flew through. Names matter at the App Store layer in…
Cruiser+ is now a real iOS app. The location stack uses CoreLocation directly (not the cross-platform Tauri location plugin — too generic, too much overhead) for the gay/leather venue heatmap. Two-finger pinch + 60Hz scroll on the map; the latter required UIScrollView.decelerationRate = .fast . Code signing took the longest. App Store distribution needs a Distribution certificate, not the…
Wrote up the SECURITY.md plus a "current status" analysis. The status analysis is the doc I wish more crypto SDKs shipped: an honest table of what's audited, what's not, and what's "implemented but please don't run this in production yet". The threat model section is short. Three lines: The SDK assumes the host machine is not compromised. The SDK does not protect against rubber-hose cryptanalysis.…
Shipped @zera-sdk/mcp — a Model Context Protocol server that exposes the SDK's note/commitment/nullifier API as a JSON-RPC tool surface. AI agents (Claude, GPT, etc.) can now mintNote , transferShielded , verifyProof directly without learning the wire format. Asymmetric tool surface design: the MCP exposes only read + simulate by default. Mutating calls require an explicit --allow-mutations flag…
The bottom-up SDK API was great for crypto folks but hostile to first-time users. Added ZeraClient — a single class that wraps RPC, prover, and note storage behind ergonomic methods like client.send({ to, amount }) and client.balance() . NoteStore is the persistence layer: by default in-memory, optionally backed by IndexedDB (browser) or SQLite (node). The contract is small: add(note) ,…
The wallet needs the Merkle root to generate proofs, and ideally the full tree to scan for owned notes. Added TreeStateClient that pulls compressed-account state from a Photon RPC, reconstructs the depth-32 Poseidon tree client-side, and verifies the on-chain root matches. Performance: 50K notes reconstructs in ~400ms. Above ~1M and the wallet should switch to lazy path-fetching (only request the…
F_RP Construction III, Approach C. Bayer-Groth verifiable shuffles obscure the input→output permutation of a batch with O(√n) proof size — used to cascade-mix pre-broadcast batches at the network layer.
The cross-platform location story before this was: macOS used CoreLocation, Windows used IP geolocation, Linux used "open a dialog and let the user type their lat/long". The first one was great; the other two were embarrassing. Windows now uses Windows.Devices.Geolocation.Geolocator via WinRT bindings (the Tauri Rust crate windows-rs makes this manageable). Linux uses geoclue2 over D-Bus. Both ask…
F_RP Construction III. ZK proofs hide the contents but the wrapping Solana tx still leaks the submitter pubkey. TAB closes that gap with a Fujisaki-Suzuki ring signature and a FROST threshold Schnorr over Ed25519.
Universal SRS, transparent FRI, and why Groth16's per-circuit ceremony feels anachronistic in 2026 — even when, as ZERA does, you're still using one. A history of the ceremonies that worked, the ones that didn't, and what comes next.
Simon's been hammering on this framing for two years and it's finally landed: any agent that has private data + untrusted input + ability to exfiltrate is, by construction, a prompt-injection victim waiting to happen. The new piece adds a clean threat-model checklist that I'm stealing for our internal review template. The screenshot of a Claude desktop integration leaking calendar entries via a…
Cloudflare Pages build kept failing with Type 'HospitalResult' is not exported . Locally astro check was happy. The reason: tsconfig.json had "include": ["src"] but the file with the type lived at src/data/types.ts — and git status showed it as untracked because I forgot to git add . Local TS resolves untracked files fine if they're in the working tree. CI clones from a SHA and only sees what was…
Why zera-sdk ships native Rust on Node and snarkjs in the browser — and what it would actually cost to ship a WASM-compiled Rust prover for the browser path. A design post about the dual-target build pipeline.
Why plonky3 — small fields, FRI commitments, no trusted setup — is the proof system to watch in 2026. The Mersenne31 / BabyBear / Goldilocks landscape, the FRI folding step, and why your laptop is suddenly a viable prover.
The path from Halo's accumulation scheme to Nova's folding scheme, derived from the recurrence relation. Where Halo2, Nova, SuperNova, and HyperNova actually differ, and which one to reach for in 2026.
F_RP Construction II. Generalises SPST to private programmable state: arbitrary arithmetic circuits over committed pre/post-state, with R1CS-embedded program execution and atomic PPST-SPST composition.
A survey of the Halo2 ecosystem six years after the Zcash team published it — what stayed the same (PLONKish, lookups, IPA), what evolved (KZG, gadget libraries, fork landscape), and what we ship today.