UNPKG

mcard-js

Version:

A JavaScript implementation of MCard - A data model for persistently storing content with cryptographic hashing and timestamping

161 lines (143 loc) 4.47 kB
import { HashAlgorithm as HashAlgorithmEnum } from './hash/enums.js'; import HashValidator from './hash/validator.js'; import { GTime as GTimeUtil } from './g_time.js'; import { HASH_ALGORITHM_HIERARCHY as ALGORITHM_HIERARCHY } from '../config/config_constants.js'; // Use global Buffer if available, otherwise use the polyfill const Buffer = global.Buffer || require('buffer').Buffer; // Destructure the enum values const { MD5, SHA1, SHA224, SHA256, SHA384, SHA512, DEFAULT } = HashAlgorithmEnum; // Event type constants const TYPE = 'type'; const HASH = 'hash'; const CONTENT_TYPE = 'content_type'; const TIMESTAMP = 'timestamp'; const EXISTING_CARD_HASH = 'existing_card_hash'; const NEW_CARD_HASH = 'new_card_hash'; const FIRST_G_TIME = 'first_g_time'; const CONTENT_SIZE = 'content_size'; const COLLISION_TIME = 'collision_time'; const UPGRADED_FUNCTION = 'upgraded_function'; const UPGRADED_HASH = 'upgraded_hash'; const DUPLICATE_TIME = 'duplicate_time'; const DUPLICATE_EVENT_TYPE = 'duplicate'; const COLLISION_EVENT_TYPE = 'collision'; // Predefined hash function progression order const HASH_FUNCTION_ORDER = ['md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512']; // Create a new HashValidator instance for use let hashValidator; // Initialize hashValidator in a try-catch to handle potential initialization errors try { hashValidator = new HashValidator(Buffer.from(''), 'sha256'); } catch (error) { console.warn('Failed to initialize hashValidator:', error); // Create a mock hashValidator if initialization fails hashValidator = { validate: () => Promise.resolve(true), computeHash: () => 'mocked-hash' }; } // Explicitly define HASH_ALGORITHM_HIERARCHY const HASH_ALGORITHM_HIERARCHY = { [MD5]: [SHA1], [SHA1]: [SHA224], [SHA224]: [SHA256], [SHA256]: [SHA384], [SHA384]: [SHA512], [SHA512]: [] }; // Replace existing nextHashFunction with method from instance function nextHashFunction(currentHashFunction) { const algMap = { 'md5': MD5, 'sha1': SHA1, 'sha224': SHA224, 'sha256': SHA256, 'sha384': SHA384, 'sha512': SHA512 }; const currFunc = algMap[currentHashFunction] || currentHashFunction; const hashFunctions = Object.values(HashAlgorithmEnum).filter( func => func !== currFunc && typeof func === 'string' ); const strongerFunctions = hashFunctions.filter(func => { const currentStrongerFuncs = HASH_ALGORITHM_HIERARCHY[currFunc] || []; return currentStrongerFuncs.includes(func); }); return strongerFunctions.length > 0 ? strongerFunctions[0] : currFunc; } // Generate a duplication event for the given card // @param {Object} card - The card being duplicated // @returns {string} JSON-stringified duplication event function generateDuplicationEvent(card) { const event = { [TYPE]: DUPLICATE_EVENT_TYPE, [HASH]: card.hash, [CONTENT_TYPE]: card.contentType, [TIMESTAMP]: GTimeUtil.stampNow(card.hashFunction || HashAlgorithmEnum.DEFAULT), [DUPLICATE_TIME]: card.g_time }; return JSON.stringify(event); } // Generate a collision event for the given event data // @param {Object} newCard - The new card // @param {Object} existingCard - The existing card // @returns {string} JSON-stringified collision event function generateCollisionEvent(newCard, existingCard = null) { const event = { type: 'collision', original_hash: existingCard ? existingCard.hash : null, new_hash: newCard.hash, timestamp: GTimeUtil.stampNow( newCard.hashFunction || existingCard?.hashFunction || HashAlgorithmEnum.DEFAULT ), content_size: typeof newCard.content === 'string' ? Buffer.from(newCard.content).length : newCard.content.length }; if (existingCard) { const upgradedFunction = nextHashFunction(existingCard.hashFunction); event.upgraded_function = upgradedFunction; event.upgraded_hash = existingCard.hash; event.hash_algorithm = upgradedFunction; } return JSON.stringify(event); } export { MD5, SHA1, SHA224, SHA256, SHA384, SHA512, TYPE, HASH, CONTENT_TYPE, TIMESTAMP, EXISTING_CARD_HASH, NEW_CARD_HASH, FIRST_G_TIME, CONTENT_SIZE, COLLISION_TIME, UPGRADED_FUNCTION, UPGRADED_HASH, DUPLICATE_TIME, DUPLICATE_EVENT_TYPE, COLLISION_EVENT_TYPE, HASH_FUNCTION_ORDER, HASH_ALGORITHM_HIERARCHY, nextHashFunction, generateDuplicationEvent, generateCollisionEvent };