Cryptomem - In-memory storage that can be accessed through custom protocol over TCP.
The repository provides two connected products:
- TCP-server to communicate with storage
- TCP-client to communicate with TCP-server and additionally encrypt your data
sequenceDiagram
participant U as User
participant C as TCP-Client
participant S as TCP-Server
participant St as In-Memory Storage
U->>C: Send Data ("Secret")
Note over C: Encrypting Data
C->>S: Custom Protocol Packet
S->>St: Store Encrypted Data
St-->>S: OK
S-->>C: Success Response
.
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── config/
│ │ └── config.go
│ ├── crypto /
│ │ └── crypto.go
│ ├── storage /
│ │ └── storage.go
│ └── transport /
│ └── transport.go
└── pkg/
└── client/
└── client.go
- cmd/server — Main executable for the TCP storage server.
- internal/crypto — Implementation of encryption logic (AES).
- internal/storage — Thread-safe in-memory engine with RWMutex.
- internal/transport — Custom binary protocol handling.
- pkg/client — Developer SDK for integrating with Cryptomem.
- ⚡ Custom TCP Protocol – Optimized binary format for fast and efficient data exchange.
- 🔒 Client-side Encryption – End-to-end security using AES. Data is encrypted before transmission, so the server never sees your plain text.
- 🧵 Thread-Safe – Built with
sync.RWMutexto handle concurrent requests safely and efficiently. - 🧹 Background Janitor – A dedicated goroutine that monitors item expiration (TTL) and performs automatic memory cleanup.
Cryptomem uses a custom binary protocol over TCP for minimal overhead and maximum performance.
The server expects requests in the following binary format:
| Offset | Size (Bytes) | Field | Description |
|---|---|---|---|
| 0 | 2 | Magic | Protocol identifier: "CM" |
| 2 | 1 | Command | uint8 (1: SET, 2: GET, 3: DELETE) |
| 3 | 2 | KeyLen | uint16 (BigEndian) — length of the key |
| 5 | 4 | ValLen | uint32 (BigEndian) — length of the value |
| 9 | 8 | TTL | int64 (BigEndian) — expiration in nanoseconds |
| 17 | KeyLen |
Key | Raw bytes of the key |
| 17 + KeyLen | ValLen |
Value | Raw bytes of the value (encrypted) |
Request Visualization:
+------+---------+---------+---------+---------+---------+-----------+
| Magic| Command | KeyLen | ValLen | TTL | Key | Value |
| (2B) | (1B) | (2B) | (4B) | (8B) | (KeyLen)| (ValLen) |
+------+---------+---------+---------+---------+---------+-----------+
The server replies with a status code and optional payload:
| Offset | Size (Bytes) | Field | Description |
|---|---|---|---|
| 0 | 2 | Magic | Protocol identifier: "CM" |
| 2 | 1 | Status | uint8 (0: Not Found, 1: OK, 2: Error) |
| 3 | 4 | ValLen | uint32 (BigEndian) — length of the returned value |
| 7 | ValLen |
Value | Raw bytes of the requested data |
Response Visualization:
+------+---------+---------+-----------+
| Magic| Status | ValLen | Value |
| (2B) | (1B) | (4B) | (ValLen) |
+------+---------+---------+-----------+
Clone the repository and download dependencies:
git clone https://github.com/Zezezknight/cryptomem.git
cd cryptomem
go mod downloadTo start the Cryptomem storage server, run the main.go file from the cmd/server directory. By default, it will listen for incoming TCP connections.
# Run the server
go run cmd/server/main.goNote: You can configure the port and storage settings in config.yaml, via environment variables or flags.
To interact with the storage from your own Go application, import the pkg/client package. The client handles the custom protocol and automatic encryption.
package main
import (
"log"
"time"
"github.com/Zezezknight/cryptomem/pkg/client"
)
func main() {
// 1. Initialize the client with server address and your encryption key
// The key is used for AES encryption/decryption on the client side
addr := "localhost:8080"
secretKey := "your-32-byte-very-secret-key-!!!"
cmClient := client.New(addr, 60*time.Second, secretKey)
// 2. Set a value (it will be encrypted before sending)
err := cmClient.Set("user_session", "active_data_payload")
if err != nil {
log.Fatalf("Failed to set value: %v", err)
}
// 3. Get a value (it will be decrypted automatically)
value, err := cmClient.Get("user_session")
if err != nil {
log.Fatalf("Failed to get value: %v", err)
}
log.Printf("Retrieved value: %s", value)
}Please note that the current TCP-Client implementation is not thread-safe.
- Single Connection: The client uses a single persistent TCP connection. Simultaneous calls to
Set()orGet()from multiple goroutines without external synchronization will lead to data corruption or protocol errors. - Recommendation: If you need to access the storage from multiple goroutines, please use a
sync.Mutexto wrap client calls or create a separate client instance for each worker/goroutine.