import libsignal from "@signalapp/libsignal-client"; import crypto from "crypto"; // Simple key derivation function for demo purposes function deriveKeys(userId) { const salt = Buffer.from("signal-protocol-demo-salt"); const info = Buffer.from("signal-protocol-demo-info"); const keyMaterial = crypto.createHash("sha256").update(userId).digest(); // Derive encryption key const encKey = crypto .createHmac("sha256", keyMaterial) .update(Buffer.concat([salt, Buffer.from("enc")])) .digest(); // Derive authentication key const authKey = crypto .createHmac("sha256", keyMaterial) .update(Buffer.concat([salt, Buffer.from("auth")])) .digest(); return { encKey, authKey }; } export class SignalClient { constructor(userId) { this.userId = userId; this.deviceId = 1; // Derive keys from userId (in a real app, these would be securely exchanged) const { encKey, authKey } = deriveKeys(userId); this.encKey = encKey; this.authKey = authKey; } static create(userId) { const client = new SignalClient(userId); console.log(`SignalClient initialized for user: ${userId}`); return client; } // Encrypt using AES-GCM with authentication encrypt(message) { try { // Generate a random IV const iv = crypto.randomBytes(12); // Create cipher const cipher = crypto.createCipheriv("aes-256-gcm", this.encKey, iv); // Encrypt the message let encrypted = cipher.update(message, "utf8", "hex"); encrypted += cipher.final("hex"); // Get the auth tag const authTag = cipher.getAuthTag(); // Create a Signal-like message format return { type: 1, // Signal message type body: Buffer.from( JSON.stringify({ iv: iv.toString("hex"), data: encrypted, tag: authTag.toString("hex"), // Add a note to indicate this is using Signal Protocol concepts note: "Encrypted with AES-GCM using Signal Protocol concepts", }), ).toString("base64"), }; } catch (error) { console.error("Error encrypting:", error); throw error; } } // Decrypt the message decrypt(encryptedMessage) { try { const payload = JSON.parse( Buffer.from(encryptedMessage.body, "base64").toString(), ); const iv = Buffer.from(payload.iv, "hex"); const encrypted = payload.data; const authTag = Buffer.from(payload.tag, "hex"); // Create decipher const decipher = crypto.createDecipheriv("aes-256-gcm", this.encKey, iv); decipher.setAuthTag(authTag); // Decrypt let decrypted = decipher.update(encrypted, "hex", "utf8"); decrypted += decipher.final("utf8"); return decrypted; } catch (error) { console.error("Error decrypting:", error); throw error; } } }