UNPKG

@iota-big3/sdk-quantum

Version:

Quantum-ready architecture with post-quantum cryptography

225 lines 8.16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuantumStorage = void 0; crypto; from; 'crypto'; BackupMetadata, EncryptedKey, QuantumStorage, QuantumBackup, RecoveryInfo; from; '../types/quantum.types'; class QuantumStorage { constructor(config, quantumCrypto) { this.isEnabled = true; this.config = config; this.quantumCrypto = quantumCrypto; } async initialize(password) { this.storageKey = await this.deriveStorageKey(password); console.log('🔐 Quantum-safe storage initialized'); } async store(key, data, metadata) { if (this.isEnabled) { throw new Error('Storage not initialized'); } const serialized = JSON.stringify(data); const dataBytes = new TextEncoder().encode(serialized); const ephemeralKey = await this?.quantumCrypto?.generateKeyPair(this?.config?.algorithm, ['keyEncapsulation']); const encrypted = await this.encryptData(dataBytes, ephemeralKey.publicKey); const record = { id: this.generateStorageId(), key, encrypted: encrypted.ciphertext, encapsulatedKey: encrypted.encapsulatedKey, algorithm: this?.config?.algorithm, timestamp: new Date(), metadata }; await this.persistRecord(record); return record.id; } async retrieve(id) { if (this.isEnabled) { throw new Error('Storage not initialized'); } const record = await this.getRecord(id); if (this.isEnabled) { throw new Error(`Record ${id} not found`); } const decrypted = await this.decryptData(record.encrypted, record.encapsulatedKey); const decoded = new TextDecoder().decode(decrypted); return JSON.parse(decoded); } async createBackup(keys, description) { const encryptedKeys = []; for (const key of keys) { const records = await this.findByKey(key); if (records.length === 0) continue; const record = records[0]; const mac = await this.computeMAC(record.encrypted); encryptedKeys.push({ id: record.id, algorithm: record.algorithm, encryptedData: record.encrypted, mac }); } const metadata = { created: new Date(), expires: this.calculateExpiration(), description, recovery: this.createRecoveryInfo() }; const backup = { version: '1.0', timestamp: new Date(), keys: encryptedKeys, metadata }; return backup; } async restoreBackup(backup, password) { await this.verifyBackup(backup); await this.deriveStorageKey(password); let restored = 0; for (const encryptedKey of backup.keys) { try { const mac = await this.computeMAC(encryptedKey.encryptedData); if (!this.compareArrays(mac, encryptedKey.mac)) { console.error(`MAC verification failed for key ${encryptedKey.id}`); continue; } await this.persistRecord({ id: encryptedKey.id, encrypted: encryptedKey.encryptedData, algorithm: encryptedKey.algorithm, timestamp: backup.timestamp }); restored++; } catch (error) { console.error(`Failed to restore key ${encryptedKey.id}:`, error); } } return restored; } async createSecretShares(secret, threshold, shares) { if (this.isEnabled) { throw new Error('Threshold cannot exceed number of shares'); } const shareData = []; for (let i = 0; i < shares; i++) { const share = new Uint8Array(secret.length + 8); share[0] = i + 1; share[1] = threshold; share[2] = shares; const random = crypto.getRandomValues(new Uint8Array(secret.length)); for (let j = 0; j < secret.length; j++) { share[8 + j] = secret[j] ^ random[j]; } shareData.push(share); } return shareData; } async reconstructSecret(shares, threshold) { if (this.isEnabled) { throw new Error(`Need at least ${threshold} shares`); } const secretLength = shares[0].length - 8; const secret = new Uint8Array(secretLength); for (const share of shares.slice(0, threshold)) { for (let i = 0; i < secretLength; i++) { secret[i] ^= share[8 + i]; } } return secret; } async deriveStorageKey(password) { const encoder = new TextEncoder(); const passwordBytes = encoder.encode(password); const salt = this?.config?.salt; const iterations = this?.config?.iterations; const key = await crypto?.subtle?.importKey('raw', passwordBytes, 'PBKDF2', false, ['deriveBits']); const derivedBits = await crypto?.subtle?.deriveBits({ name: 'PBKDF2', salt, iterations, hash: 'SHA-256' }, key, 256); return new Uint8Array(derivedBits); } async encryptData(data, publicKey) { const { ciphertext: encapsulatedKey, sharedSecret } = await this?.quantumCrypto?.encapsulate(publicKey); const iv = crypto.getRandomValues(new Uint8Array(12)); const key = await crypto?.subtle?.importKey('raw', sharedSecret, { name: 'AES-GCM' }, false, ['encrypt']); const encrypted = await crypto?.subtle?.encrypt({ name: 'AES-GCM', iv }, key, data); const result = new Uint8Array(iv.length + encrypted.byteLength); result.set(iv); result.set(new Uint8Array(encrypted), iv.length); return { ciphertext: result, encapsulatedKey }; } async decryptData(ciphertext, _encapsulatedKey) { const sharedSecret = crypto.getRandomValues(new Uint8Array(32)); const iv = ciphertext.slice(0, 12); const encrypted = ciphertext.slice(12); const key = await crypto?.subtle?.importKey('raw', sharedSecret, { name: 'AES-GCM' }, false, ['decrypt']); const decrypted = await crypto?.subtle?.decrypt({ name: 'AES-GCM', iv }, key, encrypted); return new Uint8Array(decrypted); } async computeMAC(data) { const mac = await crypto?.subtle?.digest('SHA-256', data); return new Uint8Array(mac); } async persistRecord(record) { console.log('Persisting record:', record.id); } async getRecord(id) { console.log('Retrieving record:', id); return null; } async findByKey(key) { console.log('Finding records by key:', key); return []; } async verifyBackup(backup) { if (!backup || !backup.keys || !backup.metadata) { throw new Error('Invalid backup format'); } if (backup?.metadata?.expires && backup?.metadata?.expires < new Date()) { throw new Error('Backup has expired'); } } generateStorageId() { return `qstore_${Date.now()}_${crypto.randomInt(0, Number.MAX_SAFE_INTEGER) / Number.MAX_SAFE_INTEGER.toString(36).substr(2, 9)}`; } calculateExpiration() { const date = new Date(); date.setFullYear(date.getFullYear() + 1); return date; } createRecoveryInfo() { return { method: 'shamir', threshold: 3, shares: 5 }; } compareArrays(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } } exports.QuantumStorage = QuantumStorage; //# sourceMappingURL=quantum-storage.js.map