cd /news/developer-tools/i-dna-encode-my-encrypted-database-b… · home topics developer-tools article
[ARTICLE · art-115735] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

I DNA-encode my encrypted database before writing it to disk - here's why (and why it's not "quantum" anything)

A developer built mdc-lite, a ~348KB embeddable encrypted key-value store in Rust that encodes ciphertext as DNA-like A/C/G/T strings before writing to disk. The design, part of the ModelDB repo, uses XChaCha20-Poly1305 encryption and BLAKE3-hashed filenames to prevent metadata leakage, aiming for secure storage on devices without server access.

read1 min views2 publishedAug 30, 2026

Every value in my little embedded key-value store gets encrypted, then

its ciphertext gets encoded as a string of A/C/G/T characters before it

ever touches the filesystem. Open the file in a text editor and you'll

see actual DNA-looking text - not because it's a gimmick, but because

that's genuinely the storage format.

This is mdc-lite

, a ~348KB embeddable encrypted key-value store I

built in Rust for places a server can't reach - a watch face, a phone

app, a background service. It's part of a larger repo, ModelDB,

that also includes MDC, a Python conversational data engine (query AI

models, databases, images, and documents in plain English, no SQL) with

its own DNA-inspired archival storage tier.

Every put()

call does this, in order:

[key_len][key_bytes][value_bytes]

into one plaintext buffer.[nonce][ciphertext][tag]

blob: 2 bits per base, 00→A 01→C 10→G 11→T

. Every byte maps to exactly 4 bases, so there's no padding ambiguity on decode.Filenames are keyed BLAKE3 hashes of the logical key, not the key name

itself, so a directory listing alone leaks nothing - no key names, no

values, no way to tell how many distinct keys exist versus how many

files are on disk.

rust
pub fn put(&self, key: &str, value: &[u8]) -> Result<(), LiteStoreError> {
    let mut plaintext = Vec::new();
    plaintext.extend_from_slice(&(key.len() as u16).to_le_bytes());
    plaintext.extend_from_slice(key.as_bytes());
    plaintext.extend_from_slice(value);

    let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
    let ciphertext = self.cipher().encrypt(&nonce, plaintext.as_ref())?;

    let mut record = nonce.to_vec();
    record.extend_from_slice(&ciphertext);
    let acgt_text = dna::encode(&record); // <- the actual bytes on disk

    fs::write(tmp_path, &acgt_text)?;
    fs::rename(tmp_path, final_path)?;
    Ok(())
}
── more in #developer-tools 4 stories · sorted by recency
── more on @mdc-lite 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/i-dna-encode-my-encr…] indexed:0 read:1min 2026-08-30 ·