Initial updates

This commit is contained in:
2025-09-03 19:18:19 +01:00
parent 8a6a73206e
commit eb620087c9
5 changed files with 5607 additions and 660 deletions

191
BENNC_PROTOCOL_SPEC.md Normal file
View File

@@ -0,0 +1,191 @@
# BENNC Protocol Implementation Guide
**BENNCv1** (Butlersaurus Ephemeral No NONCEnse Chat) - Complete implementation documentation for a binary pub/sub messaging protocol with encryption and compression.
## Quick Implementation Checklist
1. **Connect** to server (TCP or WebSocket)
2. **Subscribe** to message types you want to receive
3. **Encrypt** data with Romulus-M (except subscribe/unsubscribe)
4. **Send keepalive** every 30 seconds when idle
5. **Handle** incoming messages and sender IDs
## Connection Endpoints
| Protocol | Endpoint |
|----------|----------|
| TCP | `chat.3t.network:10009` |
| WebSocket (TLS) | `wss://chat.3t.network:443/BENNC` |
| WebSocket | `ws://chat.3t.network:80/BENNC` |
## Core Requirements
- **Encoding**: Big-endian integers, UTF-8 strings
- **Encryption**: Romulus-M with 16-byte nonce + message type as additional data (big-endian uint16)
- **Compression**: ZSTD (when specified per message type)
- **Max Data Size**: 1000 bytes per message (including nonce for encrypted messages)
- **Keepalive**: Send every 30 seconds when idle
- **Reserved IDs**: 0xFFFFFF00-0xFFFFFFFF for client internal use (256 IDs for local messages, system notifications, etc.)
## Message Structure
**Client → Server:**
```
┌─────────────┬─────────────┬─────────────────────────┐
│ Message Type│ Length │ Data │
│ (2 bytes) │ (2 bytes) │ (0-1000 bytes) │
└─────────────┴─────────────┴─────────────────────────┘
```
**Server → Client:**
```
┌─────────────┬─────────────┬─────────────┬─────────────────────┐
│ Message Type│ Sender ID │ Length │ Data │
│ (2 bytes) │ (4 bytes) │ (2 bytes) │ (0-1000 bytes) │
└─────────────┴─────────────┴─────────────┴─────────────────────┘
```
*Sender ID is randomly generated per connection to identify message source.*
## Encryption Implementation
**For encrypted messages (types 0x0001, 0x0002, 0x0003, 0x0006, 0x0007):**
1. Generate random 16-byte nonce
2. Prepare additional data: message type as big-endian uint16
3. Encrypt plaintext using Romulus-M AEAD
4. Prepend nonce to ciphertext
5. Total data = nonce (16 bytes) + ciphertext ≤ 1000 bytes
## Compression Implementation
- **Algorithm**: ZSTD (Zstandard) at default compression level
- **Application**: Per message type (all messages of type or none)
- **Order**: Compression applied **before** encryption
- **Scope**: Only the data portion, headers remain uncompressed
- **Currently used by**: Advanced Text Messages (0x0006, 0x0007)
## Message Types Reference
| ID | Name | Subscribable | Encrypted | Compressed | Purpose |
|----|------|--------------|-----------|------------|---------|
| 0x0000 | Subscribe | ❌ | ❌ | ❌ | Subscribe to message type |
| 0x0001 | Basic Message | ✅ | ✅ | ❌ | Chat messages |
| 0x0002 | Request User Data | ✅ | ✅ | ❌ | Request user info |
| 0x0003 | User Data Response | ✅ | ✅ | ❌ | Respond with user info |
| 0x0005 | Keepalive | ❌ | ❌ | ❌ | Prevent connection timeout |
| 0x0006 | Advanced Text | ✅ | ✅ | ✅ | Long/rich text messages |
| 0x0007 | Edit Advanced Text | ✅ | ✅ | ✅ | Edit/delete advanced text |
| 0xFFFF | Unsubscribe | ❌ | ❌ | ❌ | Unsubscribe from message type |
---
## Message Type Specifications
### Subscribe (0x0000)
Subscribe to receive messages of specified type. Must resubscribe after disconnect.
**Data:** Message type to subscribe to (2 bytes, big-endian)
---
### Basic Message (0x0001)
UTF-8 chat messages. 16-byte nonce + encrypted data ≤ 1000 bytes total.
**Data:** Encrypted UTF-8 string
---
### Request User Data (0x0002)
Request user information from all users. Clients should respond with User Data Response (0x0003).
**Data Structure:**
- Username length (2 bytes, big-endian)
- Username (up to 32 bytes, UTF-8)
- Color RGB (3 bytes: R, G, B values)
- Client identifier length (2 bytes, big-endian)
- Client identifier (up to 32 bytes, UTF-8)
---
### User Data Response (0x0003)
Send user information in response to Request User Data (0x0002).
**Data Structure:** Same as Request User Data
- Username length (2 bytes, big-endian)
- Username (up to 32 bytes, UTF-8)
- Color RGB (3 bytes: R, G, B values)
- Client identifier length (2 bytes, big-endian)
- Client identifier (up to 32 bytes, UTF-8)
---
### Keepalive (0x0005)
Prevent connection timeout when idle. Send every 30 seconds when no other traffic. Not forwarded to other clients and cannot be subscribed to.
**Data:** None - empty message
---
### Unsubscribe (0xFFFF)
Stop receiving messages of specified type.
**Data:** Message type to unsubscribe from (2 bytes, big-endian)
---
### Advanced Text (0x0006)
Multi-packet messages for long text with markdown formatting and ZSTD compression.
**Implementation Notes:**
- Text is compressed **before** splitting into packets
- Header is not compressed
- Packets may arrive out of order - use packet numbers to reconstruct
- Message ID identifies the complete message, not individual packets
- Warn users before displaying very large messages
**Data Structure:**
- Message ID (4 bytes, big-endian)
- Packet number (2 bytes, big-endian, 0-indexed)
- Final packet number (2 bytes, big-endian, 0-indexed)
- Compressed markdown text (remaining bytes, ZSTD)
### Edit Advanced Text (0x0007)
Edit or delete existing Advanced Text messages. Use same Message ID to replace existing message. Empty compressed text deletes the message. Client replaces original when final packet received.
**Data Structure:** Same as Advanced Text (0x0006)
---
## Implementation Guidelines
### Validation Requirements
- All length fields must not exceed their specified maximums
- Username/Client ID lengths must match actual string lengths
- Message data must not exceed 1000 bytes (including nonce)
- Packet numbers must be sequential and within final packet range
### Connection Lifecycle
1. **Connect** to server (TCP/WebSocket)
2. **Subscribe** to required message types
3. **Send keepalive** every 30 seconds when idle
4. **Resubscribe** after any disconnection
5. **Handle** out-of-order packets for Advanced Text
### Common Issues
- **Encryption fails**: Ensure message type in additional data matches packet header
- **Messages dropped**: Check total size ≤ 1000 bytes including nonce
- **Connection timeout**: Verify keepalive frequency
- **Advanced Text garbled**: Reconstruct packets in correct order before decompression
---
## Protocol Features
- **Binary pub/sub messaging** with server-side routing
- **End-to-end encryption** using Romulus-M AEAD
- **ZSTD compression** for large text messages
- **Multi-packet support** for long messages
- **TCP and WebSocket** transport options
This is a documentation-only repository. The protocol specification is final and changes are not permitted.

60
CLAUDE.md Normal file
View File

@@ -0,0 +1,60 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is bennc-js, a TypeScript implementation of the BENNCv1 (Butlersaurus Ephemeral No NONCEnse Chat) protocol specification. It provides client functionality for a binary pub/sub messaging protocol with encryption and compression support.
## Development Commands
- `npm run build` - Compile TypeScript to JavaScript (outputs to `dist/`)
- `npm run test` - Run Jest test suite
- `npm run lint` - Check code formatting with Prettier
- `npm run format` - Format code with Prettier
- `npm install` - Install dependencies (automatically runs `tsc` via postinstall)
## Architecture
The codebase implements the BENNC protocol specification with the following structure:
### Core Files
- `src/index.ts` - Main entry point exporting all public APIs
- `src/mapping.ts` - Central registry mapping message types (0x0000-0xFFFF) to their pack/unpack functions
- `src/common.ts` - Protocol constants including `MAX_DATA_LENGTH` (1000 bytes), `DEFAULT_KEY`, and `MessageTypes` enum
- `src/messages/packet.ts` - Core packet handling with `packOutgoingPacket` and `unpackIncomingPacket` functions
### Message Types Implementation
Each BENNC message type has its own module in `src/messages/`:
- `subscribe.ts` (0x0000) - Subscribe to message types
- `basic.ts` (0x0001) - Basic encrypted chat messages
- `userDataRequest.ts` (0x0002) - Request user information
- `userDataResponse.ts` (0x0003) - Respond with user information
- `keepalive.ts` (0x0005) - Connection keepalive messages
- `history.ts` (0xFFFE) - Message history requests
- `unsubscribe.ts` (0xFFFF) - Unsubscribe from message types
### Protocol Implementation Details
- **Binary Protocol**: Big-endian integers, UTF-8 strings
- **Message Structure**: Client sends [Type(2)|Length(2)|Data(0-1000)], Server responds [Type(2)|SenderId(4)|Length(2)|Data(0-1000)]
- **Encryption**: Uses Romulus-M AEAD (via `romulus-js` dependency) with 16-byte nonces for message types 0x0001, 0x0002, 0x0003
- **Max Data Size**: 1000 bytes including nonce for encrypted messages
- **Dependencies**: Includes local `romulus-js` cryptography implementation and `color` library for user data
### Utilities
- `src/utilities/number.ts` - Big-endian number conversion functions (`numberToUint16BE`, `numberToUint32BE`)
- `src/utilities/smart-buffer.ts` - Buffer manipulation utility for packet construction/parsing
### Key Architecture Patterns
- **Mapping System**: Central `packers` and `unpackers` objects in `mapping.ts` provide type-safe message handling
- **Interface Separation**: `IncomingPacket` vs `OutgoingPacket` interfaces handle client/server message structure differences
- **Encryption Integration**: Encrypted message types automatically handle nonce generation and Romulus-M encryption
- **Protocol Compliance**: Strict adherence to BENNC specification including reserved sender IDs (0xFFFFFF00-0xFFFFFFFF)
The codebase serves as a complete client-side implementation for connecting to BENNC chat servers via TCP or WebSocket protocols.

View File

@@ -1,5 +1,5 @@
# BENNC-JS
[![Build Status](https://drone.jacknet.io/api/badges/TerribleCodeClub/bennc-js/status.svg)](https://drone.jacknet.io/TerribleCodeClub/bennc-js) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Build Status](https://drone.jacknet.io/api/badges/TerribleCodeClub/bennc-js/status.svg)](https://drone.jacknet.io/TerribleCodeClub/bennc-js)
An implementation of the [BENNC](https://wiki.jacknet.io/books/simontech/chapter/bennc) client specification.
@@ -48,9 +48,3 @@ This repository contains the necessary configuration files to debug, test and bu
Run the build task (`Ctrl+Shift+B` or `⇧⌘B`) to automatically compile the Typescript source files in the background.
Unit tests use the [Jest](https://jestjs.io/) library. Support for Visual Studio Code is offered through the [Jest marketplace package](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest) maintained by Orta.
## Contribution guidelines
[![JavaScript Style Guide](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)
This library uses [ts-standard](https://github.com/standard/ts-standard), based on [JavaScript Standard Style](https://standardjs.com/rules.html). Please ensure all contributions are ts-standard compliant before submitting a pull request.

6003
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,8 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"lint": "ts-standard",
"lint": "prettier --check .",
"format": "prettier --write .",
"test": "jest",
"build": "tsc",
"postinstall": "tsc"
@@ -32,6 +33,6 @@
"dependencies": {
"color": "^4.2.0",
"@types/color": "^3.0.3",
"romulus-js": "git+https://git.jacknet.io/TerribleCodeClub/romulus-js.git"
"romulus-js": "file:./romulus-js"
}
}