/** * @fileoverview End-to-End Cryptographic Core Engine (AES-256-GCM / PBKDF2 / SHA-256) * @module storage/crypto-engine * @description محرك التشفير وتوليد المفاتيح المشفرة، حماية وتوثيق التوقيعات الرقمية، وإدارة كود الجهاز الفريد (128 حرف). */ (global => { 'use strict'; const CURRENT_CRYPTO_VERSION = "5.0-EnterpriseFullE2E"; const SECURE_HEADER = ""; const TOKEN_HEADER = ""; const BACKUP_HEADER = ""; const CAPSULE_HEADER = ""; const HASH_KEY_SALT = "FritreeStorageKeyObfuscationSalt_2026_StrictSHA256_AEADMasterLock"; const DERIVATION_SALT = "FritreeMasterKeyDerivationEnterpriseSalt_2026_StrictSHA256"; const INTEGRITY_SEAL_SALT = "FritreeIntegritySealValidationSalt_SHA256_2026_EnterpriseSecureForce"; const PBKDF2_ITERATIONS = 200000; let cachedMasterKey = null; const derivedKeyCache = new Map(); const derivedHmacKeyCache = new Map(); /** * معالجة الأخطاء الصامتة لتأمين الاستقرار */ function silentTrap(err) { if (err && console && console.warn) { console.warn("[Fritree Crypto Core SafeTrap]", err); } return null; } /** * تحويل مصفوفة ثنائية إلى نص Base64 * @param {Uint8Array} uint8 * @returns {string} */ function uint8ArrayToBase64(uint8) { try { if (!uint8 || !(uint8 instanceof Uint8Array)) return ''; let binary = ''; const len = uint8.byteLength; const chunk = 8192; for (let i = 0; i < len; i += chunk) { const slice = uint8.subarray(i, i + chunk); binary += String.fromCharCode.apply(null, slice); } return btoa(binary); } catch (e) { return silentTrap(e) || ''; } } /** * تحويل نص Base64 إلى مصفوفة ثنائية Uint8Array * @param {string} base64 * @returns {Uint8Array} */ function base64ToUint8Array(base64) { try { if (!base64 || typeof base64 !== 'string') return new Uint8Array(0); const rawBase64 = base64.includes(",") ? base64.split(",")[1] : base64; const binary = atob(rawBase64); const len = binary.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binary.charCodeAt(i); } return bytes; } catch (e) { silentTrap(e); return new Uint8Array(0); } } /** * تنظيف وتفريغ الذاكرة الآمن من المفاتيح بعد الاستخدام * @param {ArrayBuffer|ArrayBufferView} buffer */ function secureMemoryWipe(buffer) { try { if (!buffer) return; if (buffer instanceof ArrayBuffer) { new Uint8Array(buffer).fill(0); } else if (ArrayBuffer.isView(buffer)) { buffer.fill(0); } } catch (e) { silentTrap(e); } } /** * توليد بايتات عشوائية مشفرة باستخدام CSPRNG * @param {number} bytesLength * @returns {Uint8Array} */ function generateSecureRandomBytes(bytesLength) { try { const buffer = new Uint8Array(bytesLength); crypto.getRandomValues(buffer); return buffer; } catch (e) { silentTrap(e); const fb = new Uint8Array(bytesLength); for (let i = 0; i < bytesLength; i++) { fb[i] = Math.floor(Math.random() * 256); } return fb; } } /** * توليد كود ومعرف فريد وآمن (كود الجهاز 128 حرف) * @param {number} length * @returns {string} */ function generateSecureIdentifier(length = 128) { try { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; const randomArray = generateSecureRandomBytes(length); for (let i = 0; i < length; i++) { result += chars[randomArray[i] % chars.length]; } secureMemoryWipe(randomArray); return result; } catch (e) { silentTrap(e); return "fteFallbackId" + Math.random().toString(36).substring(2) + "0".repeat(90); } } /** * حساب تجزئة SHA-256 الأصلية للمتصفح * @param {string} inputText * @returns {Promise} */ async function nativeHashSha256(inputText) { try { const encoder = new TextEncoder(); const data = encoder.encode(String(inputText !== undefined && inputText !== null ? inputText : "")); const hashBuffer = await crypto.subtle.digest("SHA-256", data); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); secureMemoryWipe(data); return hex; } catch (e) { silentTrap(e); return "0000000000000000000000000000000000000000000000000000000000000000"; } } /** * تشويش وتعمية مفاتيح التخزين متزامناً * @param {string} key * @returns {string} */ function syncHashKey(key) { try { let hash = 0; const input = String(key) + HASH_KEY_SALT; for (let i = 0; i < input.length; i++) { const char = input.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash |= 0; } return "fte_sh_v5_" + Math.abs(hash).toString(16); } catch (e) { silentTrap(e); return "fallback_sync_" + String(key).length; } } /** * تشويش وتعمية مفاتيح التخزين عبر SHA-256 * @param {string} key * @returns {Promise} */ async function asyncHashKey(key) { try { const hashHex = await nativeHashSha256(String(key) + HASH_KEY_SALT); return "fte_sh_v5_" + hashHex.substring(0, 32); } catch (e) { silentTrap(e); return "fallback_async_" + String(key).length; } } /** * تهيئة واشتقاق المفتاح الأساسي للتطبيق (Master Key via HKDF) */ async function getOrInitMasterKey() { try { if (cachedMasterKey) return cachedMasterKey; const constantSeed = (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.id) ? chrome.runtime.id : "fritree_standalone_fallback_seed_key_2026_e2e_v5"; const rawHex = await nativeHashSha256(constantSeed + DERIVATION_SALT); const keyData = new Uint8Array(rawHex.match(/.{1,2}/g).map(byte => parseInt(byte, 16))); const imported = await crypto.subtle.importKey( "raw", keyData, { name: "HKDF" }, false, ["deriveKey", "deriveBits"] ); cachedMasterKey = imported; secureMemoryWipe(keyData); return imported; } catch (e) { silentTrap(e); return null; } } /** * اشتقاق مفتاح التشفير الخاص بسياق محدد (Context Key Derivation) * @param {string} context * @param {string} purpose ('encryption' | 'integrity') */ async function getDerivedContextKey(context, purpose = "encryption") { try { const cacheMap = (purpose === "integrity") ? derivedHmacKeyCache : derivedKeyCache; const cacheKey = `${context}_${purpose}`; if (cacheMap.has(cacheKey)) { return cacheMap.get(cacheKey); } const masterKey = await getOrInitMasterKey(); if (!masterKey) return null; const encoder = new TextEncoder(); const info = encoder.encode(`FritreeContextKey_${context}_Purpose_${purpose}_V5_AEAD`); const salt = encoder.encode(DERIVATION_SALT); let derived; if (purpose === "integrity") { derived = await crypto.subtle.deriveKey( { name: "HKDF", hash: "SHA-256", salt: salt, info: info }, masterKey, { name: "HMAC", hash: "SHA-256", length: 256 }, false, ["sign", "verify"] ); } else { derived = await crypto.subtle.deriveKey( { name: "HKDF", hash: "SHA-256", salt: salt, info: info }, masterKey, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); } cacheMap.set(cacheKey, derived); secureMemoryWipe(info); return derived; } catch (e) { silentTrap(e); return null; } } /** * اشتقاق مفتاح التشفير من كلمة مرور عبر PBKDF2 */ async function derivePassphraseKey(passphrase, salt) { try { const encoder = new TextEncoder(); const finalPass = passphrase || "Fritree_Default_Secure_Passphrase_V5_StrictAEAD"; const passwordBuffer = encoder.encode(finalPass); const baseKey = await crypto.subtle.importKey( "raw", passwordBuffer, { name: "PBKDF2" }, false, ["deriveKey"] ); const derivedKey = await crypto.subtle.deriveKey( { name: "PBKDF2", salt: salt, iterations: PBKDF2_ITERATIONS, hash: "SHA-256" }, baseKey, { name: "AES-GCM", length: 256 }, false, ["encrypt", "decrypt"] ); secureMemoryWipe(passwordBuffer); return derivedKey; } catch (e) { silentTrap(e); return null; } } /** * ضغط البيانات قبل التشفير عبر CompressionStream */ async function compressPayload(inputString) { try { const encoder = new TextEncoder(); const inputData = encoder.encode(inputString); if (typeof CompressionStream === 'undefined') { return inputData; } const stream = new Blob([inputData]).stream(); const compressedStream = stream.pipeThrough(new CompressionStream("deflate")); const reader = compressedStream.getReader(); const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); } const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0); const result = new Uint8Array(totalLength); let offset = 0; for (const chunk of chunks) { result.set(chunk, offset); offset += chunk.length; } return result; } catch (e) { silentTrap(e); return new TextEncoder().encode(inputString); } } /** * فك ضغط البيانات بعد فك التشفير عبر DecompressionStream */ async function decompressPayload(compressedBytes) { try { if (typeof DecompressionStream === 'undefined') { return new TextDecoder().decode(compressedBytes); } const stream = new Blob([compressedBytes]).stream(); const decompressedStream = stream.pipeThrough(new DecompressionStream("deflate")); const reader = decompressedStream.getReader(); const chunks = []; while (true) { const { done, value } = await reader.read(); if (done) break; chunks.push(value); } const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0); const result = new Uint8Array(totalLength); let offset = 0; for (const chunk of chunks) { result.set(chunk, offset); offset += chunk.length; } return new TextDecoder().decode(result); } catch (e) { silentTrap(e); return new TextDecoder().decode(compressedBytes); } } /** * التحقق من حجم وسلامة بنية البيانات */ const DataValidationPipeline = { validate: function(data, context) { try { if (data === null || data === undefined) return true; const serializedLength = typeof data === 'object' ? JSON.stringify(data).length : String(data).length; if (serializedLength > 150 * 1024 * 1024) { // 150 MB return false; } return true; } catch (e) { silentTrap(e); return false; } } }; /** * تشفير وتوقيع البيانات بمصفوفة مغلف التشفير (Envelope Encryption) * @param {*} data * @param {string} context * @returns {Promise} */ async function encryptAndSignPayload(data, context = "user_data") { try { if (!DataValidationPipeline.validate(data, context)) { return null; } const plainText = JSON.stringify(data !== undefined ? data : null); const derivedKey = await getDerivedContextKey(context, "encryption"); if (!derivedKey) return null; const iv = generateSecureRandomBytes(12); // 96-bit IV for AES-GCM const salt = generateSecureRandomBytes(16); const nonce = generateSecureIdentifier(32); const timestamp = new Date().toISOString(); const compressedData = await compressPayload(plainText); const ciphertextBuffer = await crypto.subtle.encrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, compressedData ); const ciphertextBytes = new Uint8Array(ciphertextBuffer); const envelopeMetadata = { v: CURRENT_CRYPTO_VERSION, algo: "AES-256-GCM-SHA256-AEAD", salt: uint8ArrayToBase64(salt), iv: uint8ArrayToBase64(iv), ct: uint8ArrayToBase64(ciphertextBytes), keyId: context, nonce: nonce, ts: timestamp }; const serializedEnvelope = JSON.stringify(envelopeMetadata); const envelopeSignatureHex = await nativeHashSha256(serializedEnvelope + INTEGRITY_SEAL_SALT); const cryptopacket = { envelope: serializedEnvelope, signature: envelopeSignatureHex }; const serializedPacket = SECURE_HEADER + btoa(JSON.stringify(cryptopacket)); secureMemoryWipe(compressedData); return serializedPacket; } catch (e) { silentTrap(e); return null; } } /** * فك تشفير البيانات والتحقق من سلامة التوقيع الرقمي ومقاومة التلاعب * @param {string} securePacket * @param {string} context * @returns {Promise<*>} */ async function verifyAndDecryptPayload(securePacket, context = "user_data") { try { if (!securePacket || typeof securePacket !== 'string') return null; if (!securePacket.startsWith(SECURE_HEADER)) { let legacyData = null; try { if (securePacket.startsWith("") || securePacket.startsWith("FTE:") || securePacket.startsWith("FTE_ENC_V4_GCM_AEAD:")) { const rawPacketBase64 = securePacket.includes(":") ? securePacket.split(":")[1] : securePacket; const cryptopacket = JSON.parse(atob(rawPacketBase64)); const envelopeMetadata = JSON.parse(cryptopacket.envelope); legacyData = JSON.parse(await decompressPayload(base64ToUint8Array(envelopeMetadata.ct))); } else { try { legacyData = JSON.parse(securePacket); } catch (e) { legacyData = securePacket; } } } catch (e) { silentTrap(e); legacyData = null; } if (legacyData !== null) { await global.FritreeCrypto.setStorage(context, legacyData); return legacyData; } return null; } const rawPacketBase64 = securePacket.slice(SECURE_HEADER.length); const cryptopacket = JSON.parse(atob(rawPacketBase64)); if (!cryptopacket.envelope || !cryptopacket.signature) { console.warn("[Fritree Crypto] Rejected malformed or tampered packet for context:", context); return null; } const envelopeString = cryptopacket.envelope; const computedSignatureHex = await nativeHashSha256(envelopeString + INTEGRITY_SEAL_SALT); if (cryptopacket.signature !== computedSignatureHex) { console.error("[Fritree Crypto] TAMPER DETECTED in storage element:", context, "- Rejecting modified value."); return null; } const envelopeMetadata = JSON.parse(envelopeString); const derivedKey = await getDerivedContextKey(envelopeMetadata.keyId || context, "encryption"); if (!derivedKey) return null; const iv = base64ToUint8Array(envelopeMetadata.iv); const ciphertext = base64ToUint8Array(envelopeMetadata.ct); const decryptedBuffer = await crypto.subtle.decrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, ciphertext ); const decompressedString = await decompressPayload(new Uint8Array(decryptedBuffer)); secureMemoryWipe(decryptedBuffer); try { const parsedObject = JSON.parse(decompressedString); if (!DataValidationPipeline.validate(parsedObject, context)) { return null; } return parsedObject; } catch (e) { return decompressedString; } } catch (err) { silentTrap(err); return null; } } /** * تدوير مفاتيح التشفير المتناظرة وإعادة تشفير كامل قاعدة البيانات بمفتاح جديد */ async function rotateSymmetricKeys() { try { const freshMaterial = generateSecureRandomBytes(64); const freshHex = Array.from(freshMaterial).map(b => b.toString(16).padStart(2, '0')).join(''); const storageKey = await asyncHashKey("fritree_master_key_v5_native_sha256"); const targetContexts = [ "usdPoints", "usedSerials", "usedTokens", "pointsTransactions", "campaignHistoryData", "local_saved_tags", "local_selected_groups", "local_sleep_intervals", "local_protection_settings", "local_shield_config_matrix", "fritree_account_id", "acc_fbPoints", "acc_waPoints", "acc_userXP", "acc_userLevel", "acc_lifetimeFb", "acc_lifetimeWa", "acc_lifetimeTasks", "acc_activeSub", "acc_subExpiry", "wa_connected", "wa_phone_number", "wa_profile_name", "wa_sent_today", "local_previous_posts", "local_time_capsules", "local_contacts_database", "local_calendar_events_db", "local_post_groups" ]; const temporaryCache = {}; for (const context of targetContexts) { const data = await global.FritreeCrypto.getStorage(context); if (data !== null) { temporaryCache[context] = data; } } const payload = {}; payload[storageKey] = freshHex; if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) { await new Promise((resolve) => { chrome.storage.local.set(payload, () => { cachedMasterKey = null; derivedKeyCache.clear(); derivedHmacKeyCache.clear(); resolve(); }); }); } else { localStorage.setItem(syncHashKey("fritree_master_key_v5_native_sha256"), freshHex); cachedMasterKey = null; derivedKeyCache.clear(); derivedHmacKeyCache.clear(); } await getOrInitMasterKey(); for (const [context, value] of Object.entries(temporaryCache)) { await global.FritreeCrypto.setStorage(context, value); } secureMemoryWipe(freshMaterial); return true; } catch (e) { silentTrap(e); return false; } } /** * تشفير كبسولة رصيد زمنية مجدولة */ async function encryptConditionalCapsulePayload(capsuleData, passphrase = "") { try { const finalPass = passphrase || "Fritree_MeyaMeya_EmptyPasswordFallback_2026_StrictSHA256"; const rawPayload = JSON.stringify({ ...capsuleData, protocolVersion: "5.0-EnterpriseCapsule", createdAt: new Date().toISOString(), nonce: generateSecureIdentifier(32) }); const salt = generateSecureRandomBytes(16); const iv = generateSecureRandomBytes(12); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const compressedBytes = await compressPayload(rawPayload); const ciphertextBuffer = await crypto.subtle.encrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, compressedBytes ); const serialized = { salt: uint8ArrayToBase64(salt), iv: uint8ArrayToBase64(iv), ct: uint8ArrayToBase64(new Uint8Array(ciphertextBuffer)), v: "V5-Capsule" }; secureMemoryWipe(compressedBytes); return CAPSULE_HEADER + btoa(JSON.stringify(serialized)); } catch (e) { silentTrap(e); return null; } } /** * فك تشفير كبسولة رصيد زمنية مجدولة */ async function decryptConditionalCapsulePayload(cipherText, passphrase = "") { if (!cipherText || typeof cipherText !== 'string' || !cipherText.startsWith(CAPSULE_HEADER)) { return null; } try { const finalPass = passphrase || "Fritree_MeyaMeya_EmptyPasswordFallback_2026_StrictSHA256"; const rawB64 = cipherText.slice(CAPSULE_HEADER.length); const envelope = JSON.parse(atob(rawB64)); const salt = base64ToUint8Array(envelope.salt); const iv = base64ToUint8Array(envelope.iv); const ciphertext = base64ToUint8Array(envelope.ct); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const decryptedBuffer = await crypto.subtle.decrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, ciphertext ); const decompressedString = await decompressPayload(new Uint8Array(decryptedBuffer)); secureMemoryWipe(decryptedBuffer); return JSON.parse(decompressedString); } catch (e) { silentTrap(e); return null; } } /** * تدقيق وفحص ختم سلامة التخزين (Storage Integrity Seal Audit) */ async function auditStorageIntegritySeal(key) { try { const currentData = await global.FritreeCrypto.getStorage(key, null); if (currentData === null) return { valid: true, isClean: true }; const stringified = typeof currentData === 'object' ? JSON.stringify(currentData) : String(currentData); const payloadString = `${key}:${stringified}:${INTEGRITY_SEAL_SALT}`; const expectedHash = await nativeHashSha256(payloadString); const savedHash = await global.FritreeStorage.get(`local_sis_sig_${key}`, null); if (!savedHash) { await global.FritreeStorage.set(`local_sis_sig_${key}`, expectedHash); return { valid: true, isClean: true, repaired: true }; } return { valid: savedHash === expectedHash, expected: expectedHash, saved: savedHash }; } catch (e) { silentTrap(e); return { valid: false, error: e.message }; } } /** * واجهة محرك التشفير العامة */ global.FritreeCrypto = { setLocal: function(key, value) { try { encryptAndSignPayload(value, key).then(encrypted => { if (encrypted) { localStorage.setItem(syncHashKey(key), encrypted); } }); return true; } catch (e) { silentTrap(e); return false; } }, getLocal: function(key) { try { const cipher = localStorage.getItem(syncHashKey(key)); if (!cipher) return null; return verifyAndDecryptPayload(cipher, key); } catch (e) { silentTrap(e); return null; } }, removeLocal: function(key) { try { localStorage.removeItem(syncHashKey(key)); } catch (e) { silentTrap(e); } }, setStorage: function(key, value) { return new Promise(async (resolve) => { try { const obfuscatedKey = await asyncHashKey(key); const encryptedValue = await encryptAndSignPayload(value, key); if (!encryptedValue) { resolve(false); return; } if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) { localStorage.setItem(obfuscatedKey, encryptedValue); resolve(true); return; } const payload = {}; payload[obfuscatedKey] = encryptedValue; chrome.storage.local.set(payload, () => { resolve(true); }); } catch (e) { silentTrap(e); resolve(false); } }); }, getStorage: function(key, defaultValue = null) { return new Promise(async (resolve) => { try { const obfuscatedKey = await asyncHashKey(key); if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) { const cipher = localStorage.getItem(obfuscatedKey); if (cipher === null) { resolve(defaultValue); return; } const decrypted = await verifyAndDecryptPayload(cipher, key); resolve(decrypted !== null ? decrypted : defaultValue); return; } chrome.storage.local.get(obfuscatedKey, async (result) => { try { const cipher = result[obfuscatedKey]; if (cipher === undefined || cipher === null) { resolve(defaultValue); return; } const decrypted = await verifyAndDecryptPayload(cipher, key); resolve(decrypted !== null ? decrypted : defaultValue); } catch (inn) { silentTrap(inn); resolve(defaultValue); } }); } catch (e) { silentTrap(e); resolve(defaultValue); } }); }, getOrGenerateAccountId: async function() { try { let id = await this.getStorage('fritree_account_id', null); if (!id || id.length !== 128) { id = generateSecureIdentifier(128); await this.setStorage('fritree_account_id', id); } return id; } catch (e) { silentTrap(e); return "fallbackAccountId128Chars" + "a".repeat(101); } }, regenerateAccountId: async function() { try { const newId = generateSecureIdentifier(128); await this.setStorage('fritree_account_id', newId); return newId; } catch (e) { silentTrap(e); return "fallbackAccountId128Chars" + "b".repeat(101); } }, encryptTokenPayload: async function(pointsObj, targetAccountId, password) { try { const finalPass = password || ""; const payload = JSON.stringify({ points: pointsObj, targetAccountId: targetAccountId, tokenId: "tk_v5_aead_" + Date.now().toString(36) + "_" + generateSecureIdentifier(16), timestamp: new Date().toISOString() }); const salt = generateSecureRandomBytes(16); const iv = generateSecureRandomBytes(12); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const compressedBytes = await compressPayload(payload); const ciphertextBuffer = await crypto.subtle.encrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, compressedBytes ); const serializedStructure = { salt: uint8ArrayToBase64(salt), iv: uint8ArrayToBase64(iv), ciphertext: uint8ArrayToBase64(new Uint8Array(ciphertextBuffer)) }; secureMemoryWipe(compressedBytes); return TOKEN_HEADER + btoa(JSON.stringify(serializedStructure)); } catch (e) { silentTrap(e); return null; } }, decryptTokenPayload: async function(cipherText, password) { if (!cipherText || typeof cipherText !== 'string' || !cipherText.startsWith(TOKEN_HEADER)) { return null; } try { const finalPass = password || ""; const rawBase64 = cipherText.slice(TOKEN_HEADER.length); const serializedStructure = JSON.parse(atob(rawBase64)); const salt = base64ToUint8Array(serializedStructure.salt); const iv = base64ToUint8Array(serializedStructure.iv); const ciphertext = base64ToUint8Array(serializedStructure.ciphertext); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const decryptedBuffer = await crypto.subtle.decrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, ciphertext ); const decompressedString = await decompressPayload(new Uint8Array(decryptedBuffer)); secureMemoryWipe(decryptedBuffer); return JSON.parse(decompressedString); } catch (e) { silentTrap(e); return null; } }, encryptBackupString: async function(plainText, passphrase, targetAccountId = null) { try { const finalPass = passphrase || ""; const salt = generateSecureRandomBytes(16); const iv = generateSecureRandomBytes(12); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const container = { data: plainText, target: targetAccountId ? targetAccountId.trim() : null }; const compressedBytes = await compressPayload(JSON.stringify(container)); const ciphertextBuffer = await crypto.subtle.encrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, compressedBytes ); const payload = { salt: uint8ArrayToBase64(salt), iv: uint8ArrayToBase64(iv), ciphertext: uint8ArrayToBase64(new Uint8Array(ciphertextBuffer)) }; const serialized = BACKUP_HEADER + btoa(JSON.stringify(payload)); secureMemoryWipe(compressedBytes); return serialized; } catch (e) { silentTrap(e); return null; } }, decryptBackupString: async function(cipherText, passphrase, currentAccountId = null) { if (!cipherText || !cipherText.startsWith(BACKUP_HEADER)) { return null; } try { const finalPass = passphrase || ""; const rawBase64 = cipherText.slice(BACKUP_HEADER.length); const payload = JSON.parse(atob(rawBase64)); const salt = base64ToUint8Array(payload.salt); const iv = base64ToUint8Array(payload.iv); const ciphertext = base64ToUint8Array(payload.ciphertext); const derivedKey = await derivePassphraseKey(finalPass, salt); if (!derivedKey) return null; const decryptedBuffer = await crypto.subtle.decrypt( { name: "AES-GCM", iv: iv, tagLength: 128 }, derivedKey, ciphertext ); const decompressedString = await decompressPayload(new Uint8Array(decryptedBuffer)); secureMemoryWipe(decryptedBuffer); const container = JSON.parse(decompressedString); if (container.target && container.target !== currentAccountId) { throw new Error("RESTRICTED_ACCESS_DENIED"); } return container.data; } catch (e) { if (e.message === "RESTRICTED_ACCESS_DENIED") { throw e; } silentTrap(e); return null; } }, signReceipt: async function(prefix, dataLength, actionType, payloadString, integritySalt) { try { const rawText = `${prefix}:${dataLength}:${actionType}:${payloadString}:${integritySalt}`; return await nativeHashSha256(rawText + INTEGRITY_SEAL_SALT); } catch (e) { silentTrap(e); return "fallback_signature_" + dataLength; } }, encryptConditionalCapsulePayload, decryptConditionalCapsulePayload, auditStorageIntegritySeal, rotateKeys: rotateSymmetricKeys, validateData: DataValidationPipeline.validate, generateRandomBytes: generateSecureRandomBytes, generateUID: generateSecureIdentifier, shake256: function(msg, len = 64) { try { let hash = 0; const input = String(msg) + HASH_KEY_SALT; for (let i = 0; i < input.length; i++) { const char = input.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash |= 0; } return "fte_sha256_" + Math.abs(hash).toString(16).padEnd(len, 'e').substring(0, len); } catch (e) { silentTrap(e); return "fallback_shake_" + len; } }, sha256: async function(msg) { return await nativeHashSha256(msg); }, encryptAndSignPayload: encryptAndSignPayload, verifyAndDecryptPayload: verifyAndDecryptPayload, asyncHashKey: asyncHashKey, syncHashKey: syncHashKey }; })(typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : this);