From 57410973347dfe8071ee0415766a9bead9d93978 Mon Sep 17 00:00:00 2001 From: RoyceDa Date: Thu, 19 Feb 2026 21:53:55 +0200 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=83=D1=82=D0=B5=D1=87=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D0=B8,=20=D0=BE=D0=BF=D1=82?= =?UTF-8?q?=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0,=20=D0=BB=D1=83=D1=87=D1=88=D0=B0=D1=8F=20=D1=87?= =?UTF-8?q?=D0=B8=D1=82=D0=B0=D0=B5=D0=BC=D0=BE=D1=81=D1=82=D1=8C=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/workers/crypto/crypto.ts | 149 ++++++++++++---------------- app/workers/crypto/crypto.worker.ts | 72 +++++--------- 2 files changed, 88 insertions(+), 133 deletions(-) diff --git a/app/workers/crypto/crypto.ts b/app/workers/crypto/crypto.ts index f809f28..8c1714d 100644 --- a/app/workers/crypto/crypto.ts +++ b/app/workers/crypto/crypto.ts @@ -1,115 +1,88 @@ import { sha256, md5 } from "node-forge"; -import { generateRandomKey } from "../../utils/utils"; import * as secp256k1 from '@noble/secp256k1'; const worker = new Worker(new URL('./crypto.worker.ts', import.meta.url), { type: 'module' }); -export const encodeWithPassword = async (password : string, data : any) : Promise => { - let task = generateRandomKey(16); - return new Promise((resolve, _) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'encodeWithPasswordResult' && event.data.task === task) { - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'encodeWithPassword', data: { password, payload: data, task } }); - }); -} +type WorkerReq = + | { id: number; type: 'encodeWithPassword'; payload: { password: string; data: any } } + | { id: number; type: 'decodeWithPassword'; payload: { password: string; data: any } } + | { id: number; type: 'encrypt'; payload: { publicKey: string; data: string } } + | { id: number; type: 'decrypt'; payload: { privateKey: string; data: string } } + | { id: number; type: 'chacha20Encrypt'; payload: { data: string } } + | { id: number; type: 'chacha20Decrypt'; payload: { ciphertext: string; nonce: string; key: string } }; -export const decodeWithPassword = (password : string, data : any) : Promise => { - let task = generateRandomKey(16); +type WorkerRes = + | { id: number; ok: true; data: any } + | { id: number; ok: false; error: string }; + +let seq = 0; +const pending = new Map void>(); + +worker.onmessage = (e: MessageEvent) => { + const res = e.data; + const cb = pending.get(res.id); + if (cb) { + pending.delete(res.id); + cb(res); + } +}; + +function callWorker(req: Omit): Promise { return new Promise((resolve, reject) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'decodeWithPasswordResult' && event.data.task === task) { - if(event.data.result === null){ - reject("Decryption failed"); - return; - } - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'decodeWithPassword', data: { password, payload: data, task } }); + const id = ++seq; + pending.set(id, (res) => (res.ok ? resolve(res.data) : reject(res.error))); + worker.postMessage({ ...req, id }); }); } -export const generateKeyPairFromSeed = async (seed : string) => { - //generate key pair using secp256k1 includes privatekey from seed +export const encodeWithPassword = (password: string, data: any): Promise => { + return callWorker({ type: 'encodeWithPassword', payload: { password, data } }); +}; + +export const decodeWithPassword = (password: string, data: any): Promise => { + return callWorker({ type: 'decodeWithPassword', payload: { password, data } }); +}; + +export const encrypt = (data: string, publicKey: string): Promise => { + return callWorker({ type: 'encrypt', payload: { publicKey, data } }); +}; + +export const decrypt = (data: string, privateKey: string): Promise => { + return callWorker({ type: 'decrypt', payload: { privateKey, data } }); +}; + +export const chacha20Encrypt = (data: string): Promise => { + return callWorker({ type: 'chacha20Encrypt', payload: { data } }); +}; + +export const chacha20Decrypt = (ciphertext: string, nonce: string, key: string): Promise => { + return callWorker({ type: 'chacha20Decrypt', payload: { ciphertext, nonce, key } }); +}; + +export const generateKeyPairFromSeed = async (seed: string) => { const privateKey = sha256.create().update(seed).digest().toHex().toString(); const publicKey = secp256k1.getPublicKey(Buffer.from(privateKey, "hex"), true); return { privateKey: privateKey, publicKey: Buffer.from(publicKey).toString('hex'), }; +}; -} - -export const encrypt = async (data : string, publicKey : string) : Promise => { - let task = generateRandomKey(16); - return new Promise((resolve, _) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'encryptResult' && event.data.task === task) { - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'encrypt', data: { publicKey, payload: data, task } }); - }); -} - -export const decrypt = async (data : string, privateKey : string) : Promise => { - let task = generateRandomKey(16); - return new Promise((resolve, reject) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'decryptResult' && event.data.task === task) { - if(event.data.result === null){ - reject("Decryption failed"); - return; - } - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'decrypt', data: { privateKey, payload: data, task } }); - }); -} - -export const chacha20Encrypt = async (data : string) => { - let task = generateRandomKey(16); - return new Promise((resolve, _) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'chacha20EncryptResult' && event.data.task === task) { - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'chacha20Encrypt', data: { payload: data, task } }); - }); -} - -export const chacha20Decrypt = async (ciphertext : string, nonce : string, key : string) => { - let task = generateRandomKey(16); - return new Promise((resolve, _) => { - worker.addEventListener('message', (event: MessageEvent) => { - if (event.data.action === 'chacha20DecryptResult' && event.data.task === task) { - resolve(event.data.result); - } - }); - worker.postMessage({ action: 'chacha20Decrypt', data: { ciphertext, nonce, key, task } }); - }); -} - -export const generateMd5 = async (data : string) => { +export const generateMd5 = async (data: string) => { const hash = md5.create(); hash.update(data); return hash.digest().toHex(); -} +}; -export const generateHashFromPrivateKey = async (privateKey : string) => { +export const generateHashFromPrivateKey = async (privateKey: string) => { return sha256.create().update(privateKey + "rosetta").digest().toHex().toString(); -} +}; -export const isEncodedWithPassword = (data : string) => { - try{ +export const isEncodedWithPassword = (data: string) => { + try { atob(data).split(":"); return true; - } catch(e) { + } catch (e) { return false; } -} +}; \ No newline at end of file diff --git a/app/workers/crypto/crypto.worker.ts b/app/workers/crypto/crypto.worker.ts index ed5b8aa..884e063 100644 --- a/app/workers/crypto/crypto.worker.ts +++ b/app/workers/crypto/crypto.worker.ts @@ -6,53 +6,35 @@ import * as secp256k1 from '@noble/secp256k1'; self.onmessage = async (event: MessageEvent) => { - const { action, data } = event.data; + const { id, type, payload } = event.data; - switch (action) { - case 'encodeWithPassword': { - const { password, payload, task } = data; - const result = await encodeWithPassword(password, payload); - self.postMessage({ action: 'encodeWithPasswordResult', result, task }); - break; + try { + let result; + switch (type) { + case 'encodeWithPassword': + result = await encodeWithPassword(payload.password, payload.data); + break; + case 'decodeWithPassword': + result = await decodeWithPassword(payload.password, payload.data); + break; + case 'encrypt': + result = await encrypt(payload.publicKey, payload.data); + break; + case 'decrypt': + result = await decrypt(payload.privateKey, payload.data); + break; + case 'chacha20Encrypt': + result = await chacha20Encrypt(payload.data); + break; + case 'chacha20Decrypt': + result = await chacha20Decrypt(payload.ciphertext, payload.nonce, payload.key); + break; + default: + throw new Error(`Unknown action: ${type}`); } - case 'chacha20Encrypt': { - const { payload, task } = data; - const result = await chacha20Encrypt(payload); - self.postMessage({ action: 'chacha20EncryptResult', result, task }); - break; - } - case 'chacha20Decrypt': { - const { ciphertext, nonce, key, task } = data; - const result = await chacha20Decrypt(ciphertext, nonce, key); - self.postMessage({ action: 'chacha20DecryptResult', result, task }); - break; - } - case 'decodeWithPassword': { - const { password, payload, task } = data; - try{ - const result = await decodeWithPassword(password, payload); - self.postMessage({ action: 'decodeWithPasswordResult', result, task }); - return; - }catch(e){ - const result = null; - self.postMessage({ action: 'decodeWithPasswordResult', result, task }); - } - break; - } - case 'decrypt': { - const { payload: encryptedData, privateKey, task } = data; - const result = await decrypt(encryptedData, privateKey); - self.postMessage({ action: 'decryptResult', result, task }); - break; - } - case 'encrypt': { - const { payload: plainData, publicKey, task } = data; - const result = await encrypt(plainData, publicKey); - self.postMessage({ action: 'encryptResult', result, task }); - break; - } - default: - console.error(`Unknown action: ${action}`); + self.postMessage({ id, ok: true, data: result }); + } catch (error) { + self.postMessage({ id, ok: false, error: String(error) }); } };