Borg/js/borg-stmf
snider 22e42d721a feat: SMSG v2 binary format with zstd compression + RFC-001 spec
- Add SMSG v2 format: binary attachments instead of base64 (~25% smaller)
   - Add zstd compression (klauspost/compress) - faster than gzip
   - Add RFC-001: Open Source DRM specification (status: Proposed)
   - Add live demo page at demo.dapp.fm with WASM decryption
   - Add mkdemo tool for generating encrypted demo files
   - Update README with proper documentation
   - Add format examples and failure case documentation

   Demo: https://demo.dapp.fm
   Master Password: PMVXogAJNVe_DDABfTmLYztaJAzsD0R7
2026-01-10 19:57:33 +00:00
..
dist feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
src feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
artist-portal.html feat: Add dapp.fm native desktop player (Wails) 2026-01-06 18:42:30 +00:00
demo-track.smsg feat: Add dapp.fm native desktop player (Wails) 2026-01-06 18:42:30 +00:00
demo.html feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
index.html feat: Zero-Trust DRM - EUPL-1.2 - Viva La OpenSource <3 2026-01-06 16:53:58 +00:00
media-player.html feat: Add dapp.fm native desktop player (Wails) 2026-01-06 18:42:30 +00:00
package.json feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
README.md feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
stmf.wasm feat: SMSG v2 binary format with zstd compression + RFC-001 spec 2026-01-10 19:57:33 +00:00
support-reply.html feat: Zero-Trust DRM - EUPL-1.2 - Viva La OpenSource <3 2026-01-06 16:53:58 +00:00
tsconfig.json feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00
wasm_exec.js feat: Add STMF form encryption and SMSG secure message packages 2025-12-27 00:49:07 +00:00

@borg/stmf

Sovereign Form Encryption - Client-side form encryption using X25519 + ChaCha20-Poly1305.

Overview

BorgSTMF encrypts HTML form data in the browser before submission, using the server's public key. Even if a MITM proxy intercepts the request, they only see encrypted data.

Installation

npm install @borg/stmf

Quick Start

<!-- Load the WASM support -->
<script src="wasm_exec.js"></script>

<!-- Your form -->
<form id="login" action="/api/login" method="POST" data-stmf="YOUR_PUBLIC_KEY_BASE64">
  <input name="email" type="email" required>
  <input name="password" type="password" required>
  <button type="submit">Login</button>
</form>

<script type="module">
import { BorgSTMF } from '@borg/stmf';

const borg = new BorgSTMF({
  serverPublicKey: 'YOUR_PUBLIC_KEY_BASE64',
  wasmPath: '/wasm/stmf.wasm'
});

await borg.init();
borg.enableInterceptor();
</script>

Manual Encryption

import { BorgSTMF } from '@borg/stmf';

const borg = new BorgSTMF({
  serverPublicKey: 'YOUR_PUBLIC_KEY_BASE64'
});

await borg.init();

// Encrypt form element
const form = document.querySelector('form');
const result = await borg.encryptForm(form);
console.log(result.payload); // Base64 encrypted STMF

// Or encrypt key-value pairs directly
const result = await borg.encryptFields({
  email: 'user@example.com',
  password: 'secret'
});

Server-Side Decryption

Go Middleware

import "github.com/Snider/Borg/pkg/stmf/middleware"

privateKey := os.Getenv("STMF_PRIVATE_KEY")
handler := middleware.Simple(privateKeyBytes)(yourHandler)

// In your handler, form values are automatically decrypted:
email := r.FormValue("email")

PHP

use Borg\STMF\STMF;

$stmf = new STMF($privateKeyBase64);
$formData = $stmf->decrypt($_POST['_stmf_payload']);

$email = $formData->get('email');

Key Generation

Generate a keypair for your server:

import "github.com/Snider/Borg/pkg/stmf"

kp, _ := stmf.GenerateKeyPair()
fmt.Println("Public key:", kp.PublicKeyBase64())  // Share this
fmt.Println("Private key:", kp.PrivateKeyBase64()) // Keep secret!

Security

  • Hybrid encryption: X25519 ECDH key exchange + ChaCha20-Poly1305
  • Forward secrecy: Each form submission uses a new ephemeral keypair
  • Authenticated encryption: Data integrity is verified on decryption
  • No passwords transmitted: Only the public key is in the HTML