UNPKG

@ayxdele/kinetic-keys

Version:

A comprehensive post-quantum cryptography library featuring Dilithium digital signatures and Kyber key encapsulation mechanisms. Includes versatile encoding schemes, key derivation utilities, and unique ID generation. Designed for quantum-resistant applic

152 lines (127 loc) 3.9 kB
// PSEUDO-CODE // # User B generates their Unlock Hash (UH) // FUNCTION generateUnlockHash(passphrase): // return HASH(passphrase) # Secure one-way hash // done. const crypto = require("crypto"); const argon2 = require("argon2"); const base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; function encodeBase62(buffer) { let num = BigInt("0x" + buffer.toString("hex")); let encoded = ""; while (num > 0) { encoded = base62[num % 62n] + encoded; num = num / 62n; } return encoded || "0"; } function base62Decode(str) { let num = BigInt(0); for (const char of str) { num = num * 62n + BigInt(base62.indexOf(char)); } const hex = num.toString(16); return Buffer.from(hex.length % 2 ? "0" + hex : hex, "hex"); } function xorBuffers(buf1, buf2) { const result = Buffer.alloc(Math.min(buf1.length, buf2.length)); for (let i = 0; i < result.length; i++) { result[i] = buf1[i] ^ buf2[i]; } return result; } // Generate Unlock Hash — single or dual mode async function generateUnlockHash(passphraseA, passphraseB = null, mode = "single") { const salt = crypto.randomBytes(16); if (mode === "dual") { if (!passphraseB) throw new Error("Dual mode requires two passphrases."); const keyA = await argon2.hash(passphraseA, { type: argon2.argon2id, salt, hashLength: 32, timeCost: 3, memoryCost: 2 ** 16, parallelism: 2, raw: true }); const keyB = await argon2.hash(passphraseB, { type: argon2.argon2id, salt, hashLength: 32, timeCost: 3, memoryCost: 2 ** 16, parallelism: 2, raw: true }); const hmacA = crypto.createHmac("sha256", keyA).update(salt).digest(); const hmacB = crypto.createHmac("sha256", keyB).update(salt).digest(); const xorHash = xorBuffers(hmacA, hmacB); const encodedXor = encodeBase62(xorHash).slice(0, 30); const checksumA = encodeBase62(hmacA.subarray(0, 3)); const checksumB = encodeBase62(hmacB.subarray(0, 3)); return `dual.${salt.toString("hex")}.${encodedXor}.${checksumA}.${checksumB}`; } // single mode const key = await argon2.hash(passphraseA, { type: argon2.argon2id, salt, hashLength: 32, timeCost: 3, memoryCost: 2 ** 16, parallelism: 2, raw: true }); const hmac = crypto.createHmac("sha256", key).update(passphraseA).digest(); return `${salt.toString("hex")}.${encodeBase62(hmac).slice(0, 15)}`; } // Verify Unlock Hash — single or dual mode async function verifyUnlockHash(storedUnlockHash, inputPassphrase, mode = "single") { const parts = storedUnlockHash.split("."); let saltHex, storedHash; if (mode === "dual" || storedUnlockHash.startsWith("dual.")) { const [_, __, encodedXor, checksumA, checksumB] = parts; saltHex = parts[1]; const salt = Buffer.from(saltHex, "hex"); const key = await argon2.hash(inputPassphrase, { type: argon2.argon2id, salt, hashLength: 32, timeCost: 3, memoryCost: 2 ** 16, parallelism: 2, raw: true }); const hmac = crypto.createHmac("sha256", key).update(salt).digest(); const testChecksum = encodeBase62(hmac.subarray(0, 3)); return testChecksum === checksumA || testChecksum === checksumB; } // single mode if (parts.length === 3) { [, saltHex, storedHash] = parts; } else if (parts.length === 2) { [saltHex, storedHash] = parts; } else { throw new Error("Invalid unlock hash format."); } const salt = Buffer.from(saltHex, "hex"); const key = await argon2.hash(inputPassphrase, { type: argon2.argon2id, salt, hashLength: 32, timeCost: 3, memoryCost: 2 ** 16, parallelism: 2, raw: true }); const hmac = crypto.createHmac("sha256", key).update(inputPassphrase).digest(); const generatedHash = encodeBase62(hmac).slice(0, 15); return generatedHash === storedHash; } module.exports = { generateUnlockHash, verifyUnlockHash, // Export internal functions for testing base62Decode, xorBuffers, encodeBase62 };