How We Test Encryption Without a Security Team

Short answer: We don't test encryption. We verify we didn't break it. The difference matters.

The Problem: Why Encryption Is Harder Than It Looks

I thought encryption was simple. Take a field, run it through AES-256-GCM, save it. Done. I was even proud of myself. Two weeks to implement. Works, doesn't crash.

Maya broke it in twenty minutes. Not the encryption itself — my assumptions.

"You're using Argon2id," she wrote. "This is 2012. RFC 9106 says: Argon2id for interactive use. What are your key derivation parameters?"

She attached a screenshot of a calculator. Her work computer — she calls it her "gaming rig," though it actually has an RTX 4090 — would crack my 6-character password in three hours.

I stared at the screen. "I thought memory-hard derivation was secure."

"It was. In 2012."

I didn't know what to say. I didn't know what RFC 9106 was. I knew what AES-256-GCM was because it sounds good in marketing (for what the cipher actually does, see AES-256-GCM explained). Argon2id I'd read about in the same article everyone reads, and decided it was enough.

That's when I realized: cryptography isn't a library you add. It's a discipline you practice. And I'm at zero.

About Maya

Maya is a young woman. Pretty, if anyone still thinks that's relevant in the context of encryption. I do, because I'm human. But when she starts talking about timing attacks and side-channel leakage, you forget everything else. She speaks calmly, no pauses, no "you know what I mean." Every sentence is like a line of code: precise, no comments, no fluff.

We met a couple of years ago on a cryptography forum. She was answering a question about Argon2id. I asked a stupid question about "AES-256-GCM encryption." She replied: "That grade doesn't exist." I couldn't tell if she was offended. Then I DM'd her, apologized. She wrote back: "Don't apologize. Learn." I learned.

When I started LockMargin, I texted her on Signal. "Maya, I'm doing encryption for invoices. Will you check?" She replied three days later: "Send code." I sent it. She replied twenty minutes later: "Call me." I called. She said: "You're using Argon2id." I already knew it was bad. But when she said it, I felt like a schoolboy.

The Solution: How We Built a Security Team Without Hiring One

I rewrote the key derivation function the next day. Argon2id, 64 MB memory, 3 iterations, 4 parallel threads. Migrated all existing databases. Wrote a migration guide.

Then I realized: once isn't a system. I needed a process. Not a team — I can't afford a team. A process.

Here's what two months built.

Property-Based Testing: 1,000 Iterations in CI, 10,000 Before Release

We use proptest. Generate random inputs and verify encryption behaves predictably.

Properties we check:

Every commit — 1,000 iterations. Before release — 10,000. Full suite takes 4 minutes on my Dell Inspiron. On the Acer I call "Fujik" — because the case looks similar — it takes 2 minutes. In two months I caught 3 bugs. One of them: duplicate nonce when creating two invoices back-to-back. I'd never have found that manually. Maybe Maya would have. Maybe not.

Fuzzing: 48 Hours Before Every Release

AFL runs our encryption APIs for 48 hours straight. We feed it random binary blobs, corrupted databases, malformed keys. Finds what we didn't think of.

We run it in a separate VM with AddressSanitizer. Crashes go straight to bug report with backtrace. First time AFL found a crash in 6 hours. I thought everything was broken. Turned out — incorrect handling of empty key. Which no real user would ever enter. But I fixed it.

Static Analysis: Cargo Audit + Custom Lints

Cargo Audit catches vulnerable dependencies. Runs in CI on every PR.

Custom lints for:

Once I accidentally logged the first 16 bytes of a key while debugging. The lint caught it. I'd never have noticed.

Key Derivation: Argon2id, 64 MB, 3 Iterations, 4 Threads

RFC 9106. No exceptions. Parameters tuned so cracking is expensive, unlocking is fast. On modern hardware — under 2 seconds.

I spent three days playing with parameters. 32 MB — faster, but cheaper to attack. 128 MB — more secure, but client's laptop hangs for 5 seconds. Settled on 64. Maya said "reasonable." That was a compliment. I think.

Key Storage: OS Keychain Only

macOS Keychain. Windows DPAPI. Linux libsecret. Never to disk. Never in environment variables. Never in the database.

We use the keyring crate. It handles platforms automatically. I don't trust abstractions, but I trust this one — because I checked. Opened Credential Manager on my Dell Inspiron "workhorse," saw the LockMargin entry. Deleted the app — the entry stayed. Not ideal, but better than a file on the desktop.

Nonce Generation: Cryptographically Secure RNG

getrandom on Linux. SecRandomCopyBytes on macOS. BCryptGenRandom on Windows. Every nonce is 96 bits, as GCM requires. We check uniqueness on a million records before every release.

I once wondered: what if the OS breaks? What if the RNG outputs zeros? Maya said: "Then you have bigger problems than encryption." Fair.

The "Evil Maid" Checklist

Maya gave me 20 items. Physical access. RAM, swap, clipboard, temp files. Every item I check manually before release.

Honestly? I don't understand half of them. "Side-channel timing attacks" — I know what it is, but I'm not sure I check it right. "Secure wipe for deleted records" — I zero out memory, but SQLite might leave traces in the journal. I don't know how to verify that conclusively.

But I check. And I write down that I checked. And I admit I'm not sure. That's better than pretending everything's under control.

Peer Review for Crypto PRs

I review all PRs. But crypto changes — only with a second approval. We have a pool of three developers who signed NDAs and the review process.

Truth is? One of them is Maya. Second is me, three days later, when I've forgotten what I wrote. Third is a guy from Estonia who helped with SQLite. He's not a crypto expert, but fresh eyes are better than nothing.

The Lesson: Three Questions for Any Encryption Tool

Before you trust your data:

How are keys derived? If they say weak key derivation without dates — run. Argon2id for interactive use.

Where are keys stored? If they say "config" or hesitate — no. OS keychain only.

What testing? If they don't name specific methods — be careful. Property-based testing and fuzzing are the minimum.

I'm not saying LockMargin won't be cracked. I'm saying we make it expensive and hard. And I'm not pretending to be an expert. I'm pretending to be someone scared enough to check. If you're still deciding whether your invoices need this level of care, start with Should You Encrypt Your Invoices?.

FAQ

What testing methods do you use?

1,000 iterations of property-based tests in CI, 10,000 before release. 48 hours of fuzzing. Cargo Audit and custom lints. 20-item "Evil Maid" checklist. Peer review for crypto PRs.

Why Argon2id with 64 MB?

Matches RFC 9106 for interactive use. Expensive to brute-force, fast for the user.

Where are encryption keys stored?

Only in the OS keychain. Never on disk. Never in environment variables. Never in the database.

How do you verify nonce uniqueness?

Cryptographically secure RNG from the OS. Every nonce is 96 bits. We check uniqueness on a million records.

How can I verify your claims?

All LockMargin crypto code is open. We use the ring crate for primitives. Independent audits welcome.

What's Next

Post #5: Engineering Recurring Reactive Invoices — or how we learned that scheduling without servers is harder than it looks.

Follow the series: Building LockMargin.

P.S. — Maya agreed to stay anonymous. She's real. We didn't grab coffee — she's in Tallinn, I'm in Kharkiv, same timezone. She sent me the audit at 4 AM. I read it at 6 AM because I overslept. Didn't reply immediately because I didn't understand half of it. Replied two days later, when I got to item 7 in the checklist and realized I was doing it wrong. She wrote back: "At least you're honest." That was a compliment. I think.

Ready to own your freelance data?

Standard is $49 one-time — no subscriptions, no cloud, no data mining. Your data stays on your machine, encrypted with AES-256-GCM.

Own your tools for $49 once > Compare Pricing

What's Next

Post #5: The Engineering Behind Reactive Recurring Invoices — or how we learned that scheduling without servers is actually harder than it looks.

Continue reading the Building LockMargin series.

Vlad (Volodymyr) Shiyan, founder of LockMargin

About the Author

Vlad (Volodymyr) Shiyan — Founder & Developer, Kharkiv, Ukraine. Building LockMargin since December 2025. Offline-first invoicing for freelancers who are tired of subscriptions. Standard is $49 one-time. Read more about Vlad →

Get launch updates

One email when Early Access opens. No spam, no newsletter.

Get one practical guide each month on building a business you own

No spam. No fluff. Unsubscribe anytime.

Back to top ↑