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
JavaScript
;
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