Protocol
Encryption
HoodChat uses NaCl box — X25519 key agreement with XSalsa20-Poly1305 — the same well-studied primitives used across modern secure messaging.
Key derivation
Your wallet signs a fixed unlock message. The secret key is the first 32 bytes of SHA-512("hoodchat/x25519/v1" ‖ signature). Standard wallets sign deterministically (RFC 6979), so the same wallet always derives the same key. Some smart-contract wallets don’t; HoodChat detects a mismatch with your on-chain key and warns you.
Message envelope
What goes on-chain for each message:
version (1) | sender public key (32) | recipient public key (32) | nonce (24) | box (ciphertext + 16-byte MAC)
And what’s sealed inside the box:
from address (20) | to address (20) | length (4) | UTF-8 text | zero padding to a 32-byte boundary
- Both public keys are included so either side can open it — which is how you can read your own sent messages.
- The addresses inside are checked against the on-chain sender and recipient, so ciphertext can’t be replayed under another wallet.
- Messages longer than ~3,900 bytes are sealed into a blob stored on IPFS; only an encrypted pointer goes on-chain, so even the file location stays private.
- Decrypted text is only ever held in memory. The app caches ciphertext, never plaintext.
Source
The implementation lives in packages/sdk/src/crypto.ts, with tests covering round-trips, tampering, replay and padding. See Privacy & security for the current limits.