A production-grade secure messaging system demonstrating end-to-end encryption, forward secrecy, and modern cryptographic practices.
Features β’ Quick Start β’ Architecture β’ Usage β’ Documentation
- Overview
- Features
- Architecture
- Prerequisites
- Installation
- Quick Start
- Usage Examples
- Project Structure
- API Documentation
- Security Model
- Testing
- Troubleshooting
- Performance
- Contributing
- License
SPEAR is a full-stack encrypted messaging platform that implements military-grade cryptography using libsodium. It demonstrates modern systems programming by combining high-performance C++ cryptographic primitives with a scalable Node.js backend and multiple client interfaces.
π Military-Grade Security - ChaCha20-Poly1305 AEAD encryption
β‘ Forward Secrecy - X25519 key exchange with HKDF
π‘οΈ Replay Protection - Counter-based attack prevention
βοΈ Message Authentication - Ed25519 digital signatures
π‘ Offline Delivery - Reliable message queuing
π Multi-Interface - CLI, Web UI, and API
β
End-to-End Encryption - Zero-knowledge architecture, server cannot read messages
β
Forward Secrecy - Past messages remain secure even if keys are compromised
β
Digital Signatures - Ed25519 for message authenticity and integrity
β
Replay Protection - Session counters prevent replay attacks
β
Key Exchange - Diffie-Hellman key agreement with X25519
β
Session Management - Per-user-pair session tracking
π AEAD Encryption - ChaCha20-Poly1305 authenticated encryption
π HKDF Key Derivation - Secure session key generation
π¦ Streaming Encryption - Chunk-based file encryption for large files
ποΈ Offline Queueing - Messages stored until recipient comes online
βοΈ Native Performance - C++ crypto core with Node.js N-API bridge
π₯οΈ Multiple Interfaces - CLI client and web dashboard
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SPEAR SYSTEM β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Client Applications Layer β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β CLI Client β β Web Dashboard β β β
β β β - Registration β β - User UI β β β
β β β - Send/Receive β β - Real-time β β β
β β β - Key Mgmt β β - Monitoring β β β
β β ββββββββββ¬ββββββββββ ββββββββββ¬ββββββββββ β β
β βββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββ β
β β β β
β βββββββββββββΌβββββββββββββββββββββββββΌβββββββββββββββββββ β
β β REST API Server (Node.js) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Routes & Controllers β β β
β β β - /api/register - User registration β β β
β β β - /api/users - User lookup β β β
β β β - /api/messages - Message queue β β β
β β β - /api/sessions - Session management β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Database (SQLite) β β β
β β β - users (id, username, public_keys) β β β
β β β - sessions (counters, rotation tracking) β β β
β β β - messages (encrypted_content, metadata) β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ β
β β Node.js N-API Addon (Bridge Layer) β β
β β - generateKeypair() - encrypt() β β
β β - generateSigningKeypair() - decrypt() β β
β β - deriveSharedSecret() - sign() β β
β β - verify() β β
β ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ β
β β C++ Cryptographic Core (libsodium) β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Key Management β β β
β β β - X25519 keypair generation β β β
β β β - Ed25519 signing keypair generation β β β
β β β - Key serialization/deserialization β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Key Exchange β β β
β β β - X25519 DH shared secret derivation β β β
β β β - HKDF session key generation β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Symmetric Encryption β β β
β β β - ChaCha20-Poly1305 AEAD β β β
β β β - Counter-based nonce management β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Digital Signatures β β β
β β β - Ed25519 message signing β β β
β β β - Signature verification β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β Streaming Encryption β β β
β β β - Chunk-based file encryption (64KB chunks) β β β
β β β - Per-chunk authentication β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | Purpose | Technology |
|---|---|---|
| Crypto Core | Cryptographic primitives | C++17, libsodium 1.0.18 |
| N-API Addon | Native bridge | Node.js N-API, node-addon-api |
| REST Server | API & message queue | Node.js, Express, SQLite |
| CLI Client | Command-line interface | Node.js, Commander.js |
| Web Dashboard | Browser-based UI | HTML5, CSS3, Vanilla JS |
- Operating System: Linux (Ubuntu 20.04+, Debian, Fedora)
- Compiler: GCC 7.5+ or Clang 10+
- CMake: 3.15+
- Node.js: 18+ LTS
- npm: 8+
# Core dependencies
libsodium-dev # Cryptographic library
build-essential # GCC, g++, make
pkg-config # Library configuration
cmake # Build systemUbuntu/Debian
sudo apt-get update
sudo apt-get install -y libsodium-dev cmake build-essential pkg-config nodejs npmFedora/RHEL
sudo dnf install -y libsodium-devel cmake gcc-c++ make pkgconfig nodejs npmArch Linux
sudo pacman -S libsodium cmake base-devel nodejs npmgit clone https://github.com/Shubham0699/SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relay.git
cd SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relaymkdir build && cd build
cmake ..
make
cd ..This produces build/crypto-core/libspear_crypto.a
cd node-addon
npm install
npx node-gyp configure
npx node-gyp build
cd ..This produces node-addon/build/Release/spear_addon.node
cd server
npm install
cd ..cd cli-client
npm install
ln -s ../node-addon/build/Release/spear_addon.node ./spear_addon.node
cd ..# Test C++ library
cd build
./test_crypto_core
# Should show: Tests passed: 24, Tests failed: 0
# Test Node addon
cd ../node-addon
node test_addon.js
# Should show: All tests completed!Terminal 1:
cd server
npm startYou should see:
SPEAR Server running on port 3000
Health check: http://localhost:3000/health
Terminal 2:
cd cli-client
# Register Alice
node src/messaging-cli.js register -u alice -k ./keys/alice
# Register Bob
node src/messaging-cli.js register -u bob -k ./keys/bob# Alice sends to Bob
node src/messaging-cli.js send \
-f alice \
-t bob \
-m "Hello Bob! This message is end-to-end encrypted." \
-k ./keys/alice# Bob receives messages
node src/messaging-cli.js receive -u bob -k ./keys/bobOutput:
Fetching messages...
You have 1 new message(s):
--- Message from alice ---
Message: Hello Bob! This message is end-to-end encrypted.
Timestamp: 2024-12-18 15:30:45
Counter: 1
All messages processed
Terminal 3:
cd web-ui/public
python3 -m http.server 8080Open browser: http://localhost:8080
# Alice encrypts a file for Bob
node src/cli.js encrypt \
-i document.pdf \
-o document.pdf.enc \
-k ./keys/alice/secret.key \
-p ./keys/bob/public.key
# Bob decrypts the file
node src/cli.js decrypt \
-i document.pdf.enc \
-o document_decrypted.pdf \
-k ./keys/bob/secret.key \
-p ./keys/alice/public.key# Health check
curl http://localhost:3000/health
# List users
curl http://localhost:3000/api/users
# Get user's public key
curl http://localhost:3000/api/users/alice
# Create session
curl -X POST http://localhost:3000/api/sessions \
-H "Content-Type: application/json" \
-d '{"username1": "alice", "username2": "bob"}'const spear = require('./build/Release/spear_addon.node');
// Generate keypair
const keypair = spear.generateKeypair();
console.log('Public key:', keypair.publicKey.toString('hex'));
// Encrypt message
const key = Buffer.alloc(32, 0x42);
const nonce = Buffer.alloc(24, 0x01);
const plaintext = Buffer.from('Secret message');
const ciphertext = spear.encrypt(plaintext, key, nonce);
console.log('Encrypted:', ciphertext.toString('base64'));
// Decrypt message
const decrypted = spear.decrypt(ciphertext, key, nonce);
console.log('Decrypted:', decrypted.toString());# Alice β Bob
node src/messaging-cli.js send -f alice -t bob -m "Hi Bob!" -k ./keys/alice
# Bob β Alice
node src/messaging-cli.js send -f bob -t alice -m "Hi Alice!" -k ./keys/bob
# Alice receives
node src/messaging-cli.js receive -u alice -k ./keys/alice
# Bob receives
node src/messaging-cli.js receive -u bob -k ./keys/bobSPEAR/
βββ crypto-core/ # C++ cryptographic library
β βββ include/ # Public headers
β β βββ types.hpp # Core types (KeyPair, Nonce, etc.)
β β βββ utils.hpp # Utilities (random, encoding)
β β βββ key_management.hpp # Key generation
β β βββ key_exchange.hpp # X25519 DH + HKDF
β β βββ symmetric_crypto.hpp # ChaCha20-Poly1305
β β βββ signing.hpp # Ed25519 signatures
β β βββ streaming.hpp # Streaming encryption
β βββ src/ # Implementations
β β βββ types.cpp
β β βββ utils.cpp
β β βββ key_management.cpp
β β βββ key_exchange.cpp
β β βββ symmetric_crypto.cpp
β β βββ signing.cpp
β β βββ streaming.cpp
β βββ tests/ # Unit tests
β β βββ test_crypto_core.cpp
β βββ CMakeLists.txt # Build configuration
β
βββ node-addon/ # N-API bridge
β βββ src/
β β βββ addon.cpp # Native addon implementation
β βββ binding.gyp # Build configuration
β βββ test_addon.js # Test suite
β βββ package.json
β
βββ server/ # Node.js backend
β βββ src/
β β βββ server.js # Main server entry point
β β βββ routes/
β β β βββ index.js # API routes
β β βββ controllers/
β β β βββ userController.js
β β β βββ messageController.js
β β β βββ sessionController.js
β β βββ models/
β β βββ database.js # SQLite schema
β βββ spear.db # Database file
β βββ package.json
β
βββ cli-client/ # Command-line interface
β βββ src/
β β βββ cli.js # File encryption CLI
β β βββ messaging-cli.js # Messaging CLI
β βββ keys/ # User keys directory
β βββ package.json
β
βββ web-ui/ # Web dashboard
β βββ public/
β βββ index.html # Single-page application
β
βββ build/ # Compiled artifacts
β βββ crypto-core/
β βββ libspear_crypto.a # Static library
β
βββ CMakeLists.txt # Root CMake config
βββ CHANGELOG.md # Version history
βββ TODO.md # Development roadmap
βββ README.md # This file
βββ LICENSE # MIT License
// Generate X25519 keypair for encryption
std::optional<KeyPair> KeyManagement::generate_keypair();
// Generate Ed25519 keypair for signing
std::optional<SigningKeyPair> KeyManagement::generate_signing_keypair();
// Serialize/deserialize keys
ByteVector KeyManagement::serialize_public_key(const PublicKey& key);
std::optional<PublicKey> KeyManagement::deserialize_public_key(const ByteVector& data);// Derive shared secret using X25519 ECDH
std::optional<SharedSecret> KeyExchange::derive_shared_secret(
const SecretKey& local_secret_key,
const PublicKey& remote_public_key
);
// Derive session key using HKDF
ByteVector KeyExchange::derive_session_key(
const SharedSecret& shared_secret,
const std::string& context,
size_t key_size = SYMMETRIC_KEY_SIZE
);// Encrypt with ChaCha20-Poly1305 AEAD
std::optional<ByteVector> SymmetricCrypto::encrypt_aead(
const ByteVector& plaintext,
const SymmetricKey& key,
const Nonce& nonce,
const ByteVector& aad = {}
);
// Decrypt and verify
std::optional<ByteVector> SymmetricCrypto::decrypt_aead(
const ByteVector& ciphertext,
const SymmetricKey& key,
const Nonce& nonce,
const ByteVector& aad = {}
);// Sign message with Ed25519
std::optional<Signature> Signing::sign_message(
const ByteVector& message,
const SigningSecretKey& secret_key
);
// Verify signature
bool Signing::verify_signature(
const ByteVector& message,
const Signature& signature,
const SigningPublicKey& public_key
);// Key generation
const keypair = spear.generateKeypair();
// Returns: { publicKey: Buffer(32), secretKey: Buffer(32) }
const signingKeypair = spear.generateSigningKeypair();
// Returns: { publicKey: Buffer(32), secretKey: Buffer(64) }
// Key exchange
const sharedSecret = spear.deriveSharedSecret(secretKey, peerPublicKey);
// Returns: Buffer(32)
// Encryption/Decryption
const ciphertext = spear.encrypt(plaintext, key, nonce);
const plaintext = spear.decrypt(ciphertext, key, nonce);
// Signing/Verification
const signature = spear.sign(message, signingSecretKey);
const isValid = spear.verify(message, signature, signingPublicKey);POST /api/register
Body: { username, publicKey, signingPublicKey }
Response: { id, username, message }
GET /api/users
Response: { users: [{ id, username, created_at }] }
GET /api/users/:username
Response: { id, username, publicKey, signingPublicKey, createdAt }
POST /api/sessions
Body: { username1, username2 }
Response: { sessionId, lastCounterUser1, lastCounterUser2, rotationThreshold }
POST /api/sessions/counter
Body: { username1, username2, counter, fromUser }
Response: { success, counter, needsRotation }
POST /api/messages
Body: { fromUsername, toUsername, encryptedContent, nonce, signature, counter }
Response: { id, message }
GET /api/messages/:username
Response: { messages: [{ id, fromUsername, encryptedContent, nonce, signature, counter, createdAt }] }
DELETE /api/messages/:id
Response: { message }
GET /health
Response: { status, timestamp }
| Component | Algorithm | Key Size | Security Level |
|---|---|---|---|
| Key Exchange | X25519 (Curve25519 ECDH) | 256-bit | ~128-bit |
| Encryption | ChaCha20-Poly1305 (AEAD) | 256-bit | 256-bit |
| Signatures | Ed25519 | 256-bit (pub), 512-bit (priv) | ~128-bit |
| Key Derivation | HKDF-SHA512 | 256-bit output | 256-bit |
| Nonces | Counter-based | 192-bit | N/A |
β
Message Interception - End-to-end encryption, server never sees plaintext
β
Replay Attacks - Counter-based validation prevents message replay
β
Message Tampering - AEAD provides authenticated encryption
β
Key Compromise - Forward secrecy via ephemeral session keys
β
Impersonation - Digital signatures prove message authenticity
β Metadata Analysis - Server knows who talks to whom and when
β Compromised Endpoints - If client device is compromised, keys are exposed
β Traffic Analysis - Message size and timing can be analyzed
β Malicious Server - Server could log metadata or deny service
β MITM During Key Exchange - No key verification/fingerprinting yet
# Store keys securely
chmod 600 keys/alice/secret.key
chmod 600 keys/alice/signing_secret.key
# Use secure key generation
node src/messaging-cli.js register -u alice -k ./keys/alice
# Verify message signatures
# (automatically done in CLI receive command)
# Monitor for replay attacks
# (server tracks counters per session)cd build
./test_crypto_coreOutput:
SPEAR Crypto Core Unit Tests
=============================
=== Testing Utils Module ===
[PASS] random_bytes generation
[PASS] random_nonce generation
[PASS] to_hex encoding
[PASS] from_hex decoding
[PASS] base64 encode/decode
=== Testing Key Management Module ===
[PASS] generate_keypair
[PASS] serialize_public_key
[PASS] deserialize_public_key
[PASS] generate_signing_keypair
... (24 total tests)
=============================
Tests passed: 24
Tests failed: 0
All tests passed!
cd node-addon
node test_addon.jsTest Script (test_e2e.sh):
#!/bin/bash
echo "Starting SPEAR End-to-End Test..."
# Start server in background
cd server && npm start &
SERVER_PID=$!
sleep 2
# Register users
cd ../cli-client
node src/messaging-cli.js register -u alice -k ./test/alice
node src/messaging-cli.js register -u bob -k ./test/bob
# Send message
node src/messaging-cli.js send -f alice -t bob -m "Test message" -k ./test/alice
# Receive message
node src/messaging-cli.js receive -u bob -k ./test/bob | grep "Test message"
if [ $? -eq 0 ]; then
echo "β
E2E Test PASSED"
else
echo "β E2E Test FAILED"
fi
# Cleanup
kill $SERVER_PID
rm -rf test/Run:
chmod +x test_e2e.sh
./test_e2e.sh# Install Apache Bench
sudo apt-get install apache2-utils
# Start server
cd server && npm start &
# Run load test
ab -n 1000 -c 10 http://localhost:3000/api/users
# Results will show requests/second, latency, etc.# Install valgrind
sudo apt-get install valgrind
# Run tests with valgrind
cd build
valgrind --leak-check=full --show-leak-kinds=all ./test_crypto_core
# Should show: "All heap blocks were freed -- no leaks are possible"Test Environment:
- CPU: Intel Core i5-8250U @ 1.60GHz
- RAM: 8GB
- OS: Ubuntu 22.04 LTS
- Compiler: GCC 11.4.0
| Operation | Time | Throughput |
|---|---|---|
| Key Generation (X25519) | ~0.5ms | 2,000 ops/sec |
| Key Exchange | ~0.3ms | 3,333 ops/sec |
| Encrypt (1KB) | ~0.02ms | 50,000 ops/sec |
| Decrypt (1KB) | ~0.02ms | 50,000 ops/sec |
| Sign (1KB) | ~0.05ms | 20,000 ops/sec |
| Verify (1KB) | ~0.15ms | 6,666 ops/sec |
Message Processing:
- Messages/second: 10,000+
- Concurrent users: 1,000+
- Average latency: <5ms
- Memory per connection: ~2KB
File Encryption (64KB chunks):
- 1MB file: ~50ms
- 10MB file: ~500ms
- 100MB file: ~5s
- Throughput: ~200MB/s
Problem: Node addon compiled for different Node version
Error: Module did not self-register
Solution:
cd node-addon
npm rebuild
npx node-gyp rebuildProblem: libsodium not installed
error while loading shared libraries: libsodium.so.23
Solution:
sudo apt-get install libsodium-dev
sudo ldconfigProblem: Port 3000 occupied
Error: listen EADDRINUSE :::3000
Solution:
# Find process
sudo lsof -i :3000
# Kill it
kill -9 <PID>
# Or use different port
PORT=3001 npm startProblem: Missing C++17 support
error: 'optional' in namespace 'std' does not name a template type
Solution:
# Ensure GCC 7+ or Clang 10+
g++ --version
# Update if needed
sudo apt-get install g++-11Problem: Database locked
Error: SQLITE_BUSY: database is locked
Solution:
cd server
rm spear.db
npm startEnable verbose logging:
# Server
DEBUG=* npm start
# CLI
node src/messaging-cli.js --verbose send -f alice -t bob -m "Test"Check logs:
# Server logs
tail -f server/logs/spear.log
# System logs
journalctl -u spear -fContributions are welcome! Here's how you can help:
- Check existing issues
- Create minimal reproducible example
- Include system information (OS, Node version, compiler)
- Attach relevant logs
- Open issue with
[FEATURE]prefix - Describe use case
- Explain expected behavior
- Discuss implementation approach
# Fork and clone
git clone https://github.com/Shubham0699/SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relay.git
cd SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relay
# Create feature branch
git checkout -b feature/amazing-feature
# Make changes and test
make clean && make
npm test
# Commit with clear message
git commit -m "Add amazing feature"
# Push and create PR
git push origin feature/amazing-feature- Follow existing style
- Use 4 spaces for indentation
- Comment complex logic
- Run tests before committing
- No memory leaks (valgrind clean)
This project is licensed under the MIT License:
MIT License
Copyright (c) 2024 SPEAR Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- libsodium - Cryptographic library
- Node.js N-API - Native addon framework
- RFC 7748 - Elliptic curves (X25519)
- RFC 8439 - ChaCha20-Poly1305
- RFC 8032 - EdDSA (Ed25519)
Project Link: https://github.com/Shubham0699/SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relay
Issues: https://github.com/Shubham0699/SPEAR-Secure-Protocol-for-Encrypted-Asynchronous-Relay/issues
Email: bobadeshubham0699@gmail.com
Want to understand the internals?
- libsodium Documentation
- N-API Documentation
- Applied Cryptography
- The Illustrated TLS Connection
- Cryptographic Right Answers
If you find this project helpful, please consider giving it a star! β
Built with β€οΈ using C++17, Node.js, and libsodium