STMF (Sovereign Form Encryption): - X25519 ECDH + ChaCha20-Poly1305 hybrid encryption - Go library (pkg/stmf/) with encrypt/decrypt and HTTP middleware - WASM module for client-side browser encryption - JavaScript wrapper with TypeScript types (js/borg-stmf/) - PHP library for server-side decryption (php/borg-stmf/) - Full cross-platform interoperability (Go <-> PHP) SMSG (Secure Message): - Password-based ChaCha20-Poly1305 message encryption - Support for attachments, metadata, and PKI reply keys - WASM bindings for browser-based decryption Demos: - index.html: Form encryption demo with modern dark UI - support-reply.html: Decrypt password-protected messages - examples/smsg-reply/: CLI tool for creating encrypted replies 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| composer.json | ||
| README.md | ||
Borg STMF for PHP
Sovereign Form Encryption - Decrypt STMF payloads using X25519 + ChaCha20-Poly1305.
Requirements
- PHP 7.2 or later
ext-sodium(included in PHP 7.2+)ext-json
Installation
composer require borg/stmf
Quick Start
<?php
use Borg\STMF\STMF;
// Initialize with your private key
$stmf = new STMF($privateKeyBase64);
// Decrypt the form payload from POST
$formData = $stmf->decrypt($_POST['_stmf_payload']);
// Access form fields
$email = $formData->get('email');
$password = $formData->get('password');
// Access all fields as array
$allFields = $formData->toArray();
// Access metadata
$origin = $formData->getOrigin();
$timestamp = $formData->getTimestamp();
Laravel Integration
// In a controller
public function handleForm(Request $request)
{
$stmf = new STMF(config('app.stmf_private_key'));
$formData = $stmf->decrypt($request->input('_stmf_payload'));
// Use decrypted data
$user = User::create([
'email' => $formData->get('email'),
'password' => Hash::make($formData->get('password')),
]);
}
Key Generation
Generate a keypair in Go:
import "github.com/Snider/Borg/pkg/stmf"
kp, _ := stmf.GenerateKeyPair()
fmt.Println("Public key:", kp.PublicKeyBase64()) // Put in HTML
fmt.Println("Private key:", kp.PrivateKeyBase64()) // Put in PHP config
Or generate in PHP (for testing):
use Borg\STMF\KeyPair;
$keypair = KeyPair::generate();
echo "Public: " . $keypair->getPublicKeyBase64() . "\n";
echo "Private: " . $keypair->getPrivateKeyBase64() . "\n";
API Reference
STMF
// Constructor
$stmf = new STMF(string $privateKeyBase64);
// Decrypt a base64-encoded payload
$formData = $stmf->decrypt(string $payloadBase64): FormData;
// Decrypt raw bytes
$formData = $stmf->decryptRaw(string $payload): FormData;
// Validate without decrypting
$isValid = $stmf->validate(string $payloadBase64): bool;
// Get payload info without decrypting
$info = $stmf->getInfo(string $payloadBase64): array;
FormData
// Get a single field value
$value = $formData->get(string $name): ?string;
// Get a field object (includes type, filename, mime)
$field = $formData->getField(string $name): ?FormField;
// Get all values for a field name
$values = $formData->getAll(string $name): array;
// Check if field exists
$exists = $formData->has(string $name): bool;
// Convert to associative array
$array = $formData->toArray(): array;
// Get all fields
$fields = $formData->fields(): array;
// Get metadata
$meta = $formData->getMetadata(): array;
$origin = $formData->getOrigin(): ?string;
$timestamp = $formData->getTimestamp(): ?int;
FormField
$field->name; // Field name
$field->value; // Field value
$field->type; // Field type (text, password, file, etc.)
$field->filename; // Filename for file uploads
$field->mimeType; // MIME type for file uploads
$field->isFile(): bool; // Check if this is a file field
$field->getFileContent(): ?string; // Get decoded file content
Security
- Hybrid encryption: X25519 ECDH key exchange + ChaCha20-Poly1305
- Forward secrecy: Each form submission uses a new ephemeral keypair
- Authenticated encryption: Decryption fails if data was tampered with
- Libsodium: Uses PHP's built-in sodium extension