UNPKG

xypriss-security

Version:

XyPriss Security is an advanced JavaScript security library designed for enterprise applications. It provides military-grade encryption, secure data structures, quantum-resistant cryptography, and comprehensive security utilities for modern web applicatio

389 lines (382 loc) 15.5 kB
'use strict'; var crypto = require('crypto'); var worker_threads = require('worker_threads'); var hashUtils = require('./hash-utils.js'); var hashAlgorithms = require('../../algorithms/hash-algorithms.js'); var os = require('os'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto); /** * Hash advanced features - Optimized hash implementations */ class HashAdvanced { /** * Cryptographic agility - support for algorithm migration * @param input - Input to hash * @param options - Migration options * @returns Hash with algorithm metadata */ static agilityHash(input, options = {}) { const { primaryAlgorithm = "blake3", fallbackAlgorithms = ["sha512", "sha3-256"], futureProof = true, outputFormat = "hex", } = options; // Primary hash const primaryHash = hashAlgorithms.HashAlgorithms.secureHash(input, { algorithm: primaryAlgorithm, outputFormat: "buffer", }); // Generate fallback hashes for migration support const fallbacks = []; if (futureProof) { for (const algo of fallbackAlgorithms) { try { const fallbackHash = hashAlgorithms.HashAlgorithms.secureHash(input, { algorithm: algo, outputFormat: "hex", }); fallbacks.push(`${algo}:${fallbackHash}`); } catch (error) { console.warn(`Fallback algorithm ${algo} failed:`, error); } } } return { hash: hashUtils.HashUtils.formatOutput(primaryHash, outputFormat), algorithm: primaryAlgorithm, fallbacks, metadata: { version: "1.0.0", timestamp: Date.now(), strength: "MILITARY", }, }; } /** * Side-channel attack resistant hashing * @param input - Input to hash * @param options - Resistance options * @returns Side-channel resistant hash */ static sideChannelResistantHash(input, options = {}) { const { constantTime = true, memoryProtection = true, powerAnalysisResistant = true, outputFormat = "hex", } = options; const inputBuffer = hashUtils.HashUtils.toBuffer(input); if (constantTime) { return this.constantTimeHash(inputBuffer, memoryProtection, outputFormat); } if (powerAnalysisResistant) { return this.powerAnalysisResistantHash(inputBuffer, outputFormat); } return hashAlgorithms.HashAlgorithms.secureHash(input, { outputFormat }); } /** * Constant-time hash processing * @param inputBuffer - Input buffer * @param memoryProtection - Enable memory protection * @param outputFormat - Output format * @returns Constant-time hash */ static constantTimeHash(inputBuffer, memoryProtection, outputFormat) { // Use fixed-size buffer to prevent length-based timing attacks const blockSize = 1024; const numBlocks = Math.ceil(inputBuffer.length / blockSize); const paddedInput = Buffer.alloc(numBlocks * blockSize); inputBuffer.copy(paddedInput, 0, 0, inputBuffer.length); // Use HMAC for constant-time properties const key = crypto__namespace.randomBytes(32); const hmac = crypto__namespace.createHmac("sha256", key); // Process in fixed-size blocks for (let i = 0; i < paddedInput.length; i += blockSize) { const block = paddedInput.subarray(i, i + blockSize); hmac.update(block); } const result = hmac.digest(); // Secure memory cleanup if (memoryProtection) { paddedInput.fill(0); key.fill(0); // Force garbage collection hint if (global.gc) { global.gc(); } } return hashUtils.HashUtils.formatOutput(result, outputFormat); } /** * Power analysis resistant hash processing - optimized implementation * @param inputBuffer - Input buffer * @param outputFormat - Output format * @returns Power analysis resistant hash */ static powerAnalysisResistantHash(inputBuffer, outputFormat) { // Use multiple hash algorithms to create noise const algorithms = ["sha256", "sha512", "sha3-256"]; let result = inputBuffer; // Fixed number of rounds with different algorithms for (let i = 0; i < 3; i++) { const algo = algorithms[i % algorithms.length]; result = crypto__namespace.createHash(algo).update(result).digest(); } return hashUtils.HashUtils.formatOutput(result, outputFormat); } /** * tse.ExecutionResultparallel hash processing using worker threads * @param input - Input to hash * @param options - Parallel processing options * @returns Promise resolving to hash result */ static async parallelHash(input, options = {}) { const { chunkSize = this.CHUNK_SIZE, workers = Math.min(this.MAX_WORKERS, 4), algorithm = "sha256", outputFormat = "hex", } = options; const inputBuffer = hashUtils.HashUtils.toBuffer(input); // Use single-threaded for small inputs if (inputBuffer.length <= chunkSize) { return hashAlgorithms.HashAlgorithms.secureHash(input, { algorithm, outputFormat, }); } // Split input into chunks const chunks = []; for (let i = 0; i < inputBuffer.length; i += chunkSize) { chunks.push(inputBuffer.subarray(i, i + chunkSize)); } // Process chunks with actual worker threads const workerPromises = chunks.map((chunk, index) => { return new Promise((resolve, reject) => { const worker = new worker_threads.Worker(` const { parentPort } = require('worker_threads'); const crypto = require('crypto'); parentPort.on('message', ({ chunk, algorithm }) => { try { const hash = crypto.createHash(algorithm).update(chunk).digest(); parentPort.postMessage({ success: true, hash }); } catch (error) { parentPort.postMessage({ success: false, error: error.message }); } }); `, { eval: true }); worker.postMessage({ chunk, algorithm }); worker.on("message", ({ success, hash, error }) => { if (success) { resolve(hash); } else { reject(new Error(error)); } worker.terminate(); }); worker.on("error", reject); }); }); try { const chunkHashes = await Promise.all(workerPromises); // Combine chunk hashes const combinedHash = crypto__namespace.createHash(algorithm); for (const chunkHash of chunkHashes) { combinedHash.update(chunkHash); } const result = combinedHash.digest(); return hashUtils.HashUtils.formatOutput(result, outputFormat); } catch (error) { // Fallback to single-threaded processing console.warn("Parallel processing failed, falling back to single-threaded:", error); return hashAlgorithms.HashAlgorithms.secureHash(input, { algorithm, outputFormat, }); } } /** * Optimized streaming hash for large data processing * @param algorithm - Hash algorithm * @param options - Streaming options * @returns Stream hash processor */ static createStreamingHash(algorithm = "sha256", options = {}) { const { chunkSize = this.CHUNK_SIZE, progressCallback } = options; let hash = crypto__namespace.createHash(algorithm); let totalProcessed = 0; let chunksProcessed = 0; let buffer = Buffer.alloc(0); return { update: (chunk) => { // Accumulate data in buffer for optimal processing buffer = Buffer.concat([buffer, chunk]); // Process complete chunks while (buffer.length >= chunkSize) { const processChunk = buffer.subarray(0, chunkSize); hash.update(processChunk); buffer = buffer.subarray(chunkSize); totalProcessed += chunkSize; chunksProcessed++; if (progressCallback) { progressCallback(totalProcessed); } } }, digest: () => { // Process remaining buffer if (buffer.length > 0) { hash.update(buffer); totalProcessed += buffer.length; } const result = hash.digest(); // Reset state hash = crypto__namespace.createHash(algorithm); buffer = Buffer.alloc(0); totalProcessed = 0; chunksProcessed = 0; return result; }, reset: () => { hash = crypto__namespace.createHash(algorithm); buffer = Buffer.alloc(0); totalProcessed = 0; chunksProcessed = 0; }, getProgress: () => ({ processed: totalProcessed, chunks: chunksProcessed, }), }; } /** * Optimized Merkle tree hash for data integrity * @param data - Array of data chunks * @param algorithm - Hash algorithm * @returns Merkle root hash */ static merkleTreeHash(data, algorithm = "sha256") { if (data.length === 0) { throw new Error("Cannot create Merkle tree from empty data"); } // Pre-allocate arrays for better performance let hashes = new Array(data.length); // Hash all leaf nodes for (let i = 0; i < data.length; i++) { const buffer = hashUtils.HashUtils.toBuffer(data[i]); hashes[i] = crypto__namespace.createHash(algorithm).update(buffer).digest(); } // Build tree bottom-up with optimized memory usage while (hashes.length > 1) { const nextLevel = new Array(Math.ceil(hashes.length / 2)); let nextIndex = 0; for (let i = 0; i < hashes.length; i += 2) { if (i + 1 < hashes.length) { // Combine pair of hashes efficiently const combined = Buffer.allocUnsafe(hashes[i].length + hashes[i + 1].length); hashes[i].copy(combined, 0); hashes[i + 1].copy(combined, hashes[i].length); nextLevel[nextIndex] = crypto__namespace .createHash(algorithm) .update(combined) .digest(); } else { // Odd number of hashes, promote the last one nextLevel[nextIndex] = hashes[i]; } nextIndex++; } hashes = nextLevel; } return hashes[0]; } /** * Optimized incremental hash for append-only data * @param previousHash - Previous hash state * @param newData - New data to append * @param algorithm - Hash algorithm * @returns Updated hash */ static incrementalHash(previousHash, newData, algorithm = "sha256") { const prevBuffer = Buffer.isBuffer(previousHash) ? previousHash : Buffer.from(previousHash, "hex"); const newBuffer = hashUtils.HashUtils.toBuffer(newData); // Efficient concatenation and hashing const totalLength = prevBuffer.length + newBuffer.length; const combined = Buffer.allocUnsafe(totalLength); prevBuffer.copy(combined, 0); newBuffer.copy(combined, prevBuffer.length); return crypto__namespace.createHash(algorithm).update(combined).digest(); } /** * Optimized hash chain for sequential data integrity * @param data - Array of data items * @param algorithm - Hash algorithm * @returns Array of chained hashes */ static hashChain(data, algorithm = "sha256") { if (data.length === 0) { return []; } const hashes = new Array(data.length); let previousHash = null; for (let i = 0; i < data.length; i++) { const itemBuffer = hashUtils.HashUtils.toBuffer(data[i]); const hasher = crypto__namespace.createHash(algorithm); if (previousHash) { hasher.update(previousHash); } hasher.update(itemBuffer); const hash = hasher.digest(); hashes[i] = hash; previousHash = hash; } return hashes; } /** * Batch hash processing for multiple inputs * @param inputs - Array of inputs to hash * @param algorithm - Hash algorithm * @param outputFormat - Output format * @returns Array of hashes */ static batchHash(inputs, algorithm = "sha256", outputFormat = "hex") { const results = new Array(inputs.length); for (let i = 0; i < inputs.length; i++) { const buffer = hashUtils.HashUtils.toBuffer(inputs[i]); const hash = crypto__namespace.createHash(algorithm).update(buffer).digest(); results[i] = hashUtils.HashUtils.formatOutput(hash, outputFormat); } return results; } /** * Memory-efficient hash verification * @param input - Input to verify * @param expectedHash - Expected hash value * @param algorithm - Hash algorithm * @returns True if hash matches */ static verifyHash(input, expectedHash, algorithm = "sha256") { const inputBuffer = hashUtils.HashUtils.toBuffer(input); const computedHash = crypto__namespace .createHash(algorithm) .update(inputBuffer) .digest(); const expectedBuffer = Buffer.isBuffer(expectedHash) ? expectedHash : Buffer.from(expectedHash, "hex"); // Constant-time comparison to prevent timing attacks return crypto__namespace.timingSafeEqual(computedHash, expectedBuffer); } } HashAdvanced.CHUNK_SIZE = 64 * 1024; // 64KB HashAdvanced.MAX_WORKERS = os.cpus().length; exports.HashAdvanced = HashAdvanced; //# sourceMappingURL=hash-advanced.js.map