-
-
Save Kreijstal/db65b1d39e99ce7640a5af359be2c83a to your computer and use it in GitHub Desktop.
Revisions
-
Kreijstal revised this gist
Nov 15, 2024 . 1 changed file with 93 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -323,6 +323,99 @@ function md5(input) { .join(''); } function sha1(message, rounds = 80) { let bytes; if (typeof message === 'string') { const encoder = new TextEncoder(); bytes = encoder.encode(message); } else if (message instanceof Uint8Array) { bytes = message; } else { throw new Error("Invalid input type. Expected Uint8Array or string."); } let h0 = 0x67452301; let h1 = 0xEFCDAB89; let h2 = 0x98BADCFE; let h3 = 0x10325476; let h4 = 0xC3D2E1F0; let ml = bytes.length * 8; // Pre-processing let paddedBytes = new Uint8Array([...bytes, 0x80]); while ((paddedBytes.length * 8) % 512 !== 448) { paddedBytes = new Uint8Array([...paddedBytes, 0x00]); } const mlBytes = new Uint8Array(8); for (let i = 7; i >= 0; i--) { mlBytes[i] = ml & 0xFF; ml = ml >>> 8; } paddedBytes = new Uint8Array([...paddedBytes, ...mlBytes]); // Process the message in successive 512-bit chunks for (let i = 0; i < paddedBytes.length; i += 64) { const chunk = paddedBytes.slice(i, i + 64); let w = new Array(rounds).fill(0); for (let j = 0; j < 16; j++) { w[j] = (chunk[j * 4] << 24) | (chunk[j * 4 + 1] << 16) | (chunk[j * 4 + 2] << 8) | chunk[j * 4 + 3]; } for (let j = 16; j < rounds; j++) { w[j] = ROTL(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); } let a = h0; let b = h1; let c = h2; let d = h3; let e = h4; for (let j = 0; j < rounds; j++) { let f, k; if (0 <= j && j <= 19) { f = (b & c) | ((~b) & d); k = 0x5A827999; } else if (20 <= j && j <= 39) { f = b ^ c ^ d; k = 0x6ED9EBA1; } else if (40 <= j && j <= 59) { f = (b & c) | (b & d) | (c & d); k = 0x8F1BBCDC; } else if (60 <= j && j <= 79) { f = b ^ c ^ d; k = 0xCA62C1D6; } else { f = b ^ c ^ d; k = 0xCA62C1D6; } const temp = safeAdd32(ROTL(a, 5), safeAdd32(safeAdd32(safeAdd32(f, e), k), w[j])); e = d; d = c; c = ROTL(b, 30); b = a; a = temp; } h0 = safeAdd32(h0, a); h1 = safeAdd32(h1, b); h2 = safeAdd32(h2, c); h3 = safeAdd32(h3, d); h4 = safeAdd32(h4, e); } const hh = (h0 >>> 0).toString(16).padStart(8, '0') + (h1 >>> 0).toString(16).padStart(8, '0') + (h2 >>> 0).toString(16).padStart(8, '0') + (h3 >>> 0).toString(16).padStart(8, '0') + (h4 >>> 0).toString(16).padStart(8, '0'); return hh; } function sha256(msgBytes, rounds = 64) { -
Kreijstal revised this gist
Nov 14, 2024 . 1 changed file with 6 additions and 13 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,14 +1,7 @@ /* * Bitwise rotate a 32-bit number to the left. */ function ROTL(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } @@ -19,7 +12,7 @@ function rol(num, cnt) */ function md4_cmn(q, a, b, x, s, t) { return safeAdd32(ROTL(safeAdd32(safeAdd32(a, q), safeAdd32(x, t)), s), b); } function md4_ff(a, b, c, d, x, s) { @@ -103,10 +96,10 @@ function core_md4(x, len) c = md4_hh(c, d, a, b, x[i+ 7], 11); b = md4_hh(b, c, d, a, x[i+15], 15); a = safeAdd32(a, olda); b = safeAdd32(b, oldb); c = safeAdd32(c, oldc); d = safeAdd32(d, oldd); } return Array(a, b, c, d); -
Kreijstal revised this gist
Nov 14, 2024 . 1 changed file with 157 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,160 @@ function safe_add(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF); var msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } /* * Bitwise rotate a 32-bit number to the left. */ function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)); } /* * These functions implement the basic operation for each round of the * algorithm. */ function md4_cmn(q, a, b, x, s, t) { return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); } function md4_ff(a, b, c, d, x, s) { return md4_cmn((b & c) | ((~b) & d), a, 0, x, s, 0); } function md4_gg(a, b, c, d, x, s) { return md4_cmn((b & c) | (b & d) | (c & d), a, 0, x, s, 1518500249); } function md4_hh(a, b, c, d, x, s) { return md4_cmn(b ^ c ^ d, a, 0, x, s, 1859775393); } function core_md4(x, len) { /* append padding */ x[len >> 5] |= 0x80 << (len % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md4_ff(a, b, c, d, x[i+ 0], 3 ); d = md4_ff(d, a, b, c, x[i+ 1], 7 ); c = md4_ff(c, d, a, b, x[i+ 2], 11); b = md4_ff(b, c, d, a, x[i+ 3], 19); a = md4_ff(a, b, c, d, x[i+ 4], 3 ); d = md4_ff(d, a, b, c, x[i+ 5], 7 ); c = md4_ff(c, d, a, b, x[i+ 6], 11); b = md4_ff(b, c, d, a, x[i+ 7], 19); a = md4_ff(a, b, c, d, x[i+ 8], 3 ); d = md4_ff(d, a, b, c, x[i+ 9], 7 ); c = md4_ff(c, d, a, b, x[i+10], 11); b = md4_ff(b, c, d, a, x[i+11], 19); a = md4_ff(a, b, c, d, x[i+12], 3 ); d = md4_ff(d, a, b, c, x[i+13], 7 ); c = md4_ff(c, d, a, b, x[i+14], 11); b = md4_ff(b, c, d, a, x[i+15], 19); a = md4_gg(a, b, c, d, x[i+ 0], 3 ); d = md4_gg(d, a, b, c, x[i+ 4], 5 ); c = md4_gg(c, d, a, b, x[i+ 8], 9 ); b = md4_gg(b, c, d, a, x[i+12], 13); a = md4_gg(a, b, c, d, x[i+ 1], 3 ); d = md4_gg(d, a, b, c, x[i+ 5], 5 ); c = md4_gg(c, d, a, b, x[i+ 9], 9 ); b = md4_gg(b, c, d, a, x[i+13], 13); a = md4_gg(a, b, c, d, x[i+ 2], 3 ); d = md4_gg(d, a, b, c, x[i+ 6], 5 ); c = md4_gg(c, d, a, b, x[i+10], 9 ); b = md4_gg(b, c, d, a, x[i+14], 13); a = md4_gg(a, b, c, d, x[i+ 3], 3 ); d = md4_gg(d, a, b, c, x[i+ 7], 5 ); c = md4_gg(c, d, a, b, x[i+11], 9 ); b = md4_gg(b, c, d, a, x[i+15], 13); a = md4_hh(a, b, c, d, x[i+ 0], 3 ); d = md4_hh(d, a, b, c, x[i+ 8], 9 ); c = md4_hh(c, d, a, b, x[i+ 4], 11); b = md4_hh(b, c, d, a, x[i+12], 15); a = md4_hh(a, b, c, d, x[i+ 2], 3 ); d = md4_hh(d, a, b, c, x[i+10], 9 ); c = md4_hh(c, d, a, b, x[i+ 6], 11); b = md4_hh(b, c, d, a, x[i+14], 15); a = md4_hh(a, b, c, d, x[i+ 1], 3 ); d = md4_hh(d, a, b, c, x[i+ 9], 9 ); c = md4_hh(c, d, a, b, x[i+ 5], 11); b = md4_hh(b, c, d, a, x[i+13], 15); a = md4_hh(a, b, c, d, x[i+ 3], 3 ); d = md4_hh(d, a, b, c, x[i+11], 9 ); c = md4_hh(c, d, a, b, x[i+ 7], 11); b = md4_hh(b, c, d, a, x[i+15], 15); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); } function md4(input) { // Handle string input by converting to Uint8Array let data = input; if (typeof input === 'string') { data = new TextEncoder().encode(input); } // Calculate input length in bits const bitLength = data.length * 8; // Calculate padding length (ensure room for length at end) // Need at least 1 byte for 0x80 and 8 bytes for length // Total length must be multiple of 64 bits (8 bytes) const paddingLength = (56 - (data.length + 1) % 64 + 64) % 64; // Create padded array const paddedLength = data.length + 1 + paddingLength + 8; const paddedData = new Uint8Array(paddedLength); // Copy original data paddedData.set(data); // Add padding byte 0x80 paddedData[data.length] = 0x80; // Add original length in bits as little-endian 64-bit integer const view = new DataView(paddedData.buffer); view.setUint32(paddedLength - 8, bitLength, true); view.setUint32(paddedLength - 4, 0, true); // Convert to 32-bit array for core_md4 const words = new Uint32Array(paddedData.buffer); // Process with core_md4 const result = core_md4(Array.from(words), bitLength); // Convert result to hex string return [...new Uint8Array(new Uint32Array(result).buffer)] .map(b => b.toString(16).padStart(2, '0')) .join(''); } function safeAdd32(a, b) { return (a + b) & 0xFFFFFFFF; } -
Kreijstal revised this gist
Nov 14, 2024 . 1 changed file with 162 additions and 194 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,192 +1,181 @@ function safeAdd32(a, b) { return (a + b) & 0xFFFFFFFF; } function ROTR(n, x) { return (x >>> n) | (x << (32 - n)); } function md5cycle(x, k) { let a = x[0], b = x[1], c = x[2], d = x[3]; // Round 1 a = ff(a, b, c, d, k[0], 7, -680876936); d = ff(d, a, b, c, k[1], 12, -389564586); c = ff(c, d, a, b, k[2], 17, 606105819); b = ff(b, c, d, a, k[3], 22, -1044525330); a = ff(a, b, c, d, k[4], 7, -176418897); d = ff(d, a, b, c, k[5], 12, 1200080426); c = ff(c, d, a, b, k[6], 17, -1473231341); b = ff(b, c, d, a, k[7], 22, -45705983); a = ff(a, b, c, d, k[8], 7, 1770035416); d = ff(d, a, b, c, k[9], 12, -1958414417); c = ff(c, d, a, b, k[10], 17, -42063); b = ff(b, c, d, a, k[11], 22, -1990404162); a = ff(a, b, c, d, k[12], 7, 1804603682); d = ff(d, a, b, c, k[13], 12, -40341101); c = ff(c, d, a, b, k[14], 17, -1502002290); b = ff(b, c, d, a, k[15], 22, 1236535329); // Round 2 a = gg(a, b, c, d, k[1], 5, -165796510); d = gg(d, a, b, c, k[6], 9, -1069501632); c = gg(c, d, a, b, k[11], 14, 643717713); b = gg(b, c, d, a, k[0], 20, -373897302); a = gg(a, b, c, d, k[5], 5, -701558691); d = gg(d, a, b, c, k[10], 9, 38016083); c = gg(c, d, a, b, k[15], 14, -660478335); b = gg(b, c, d, a, k[4], 20, -405537848); a = gg(a, b, c, d, k[9], 5, 568446438); d = gg(d, a, b, c, k[14], 9, -1019803690); c = gg(c, d, a, b, k[3], 14, -187363961); b = gg(b, c, d, a, k[8], 20, 1163531501); a = gg(a, b, c, d, k[13], 5, -1444681467); d = gg(d, a, b, c, k[2], 9, -51403784); c = gg(c, d, a, b, k[7], 14, 1735328473); b = gg(b, c, d, a, k[12], 20, -1926607734); // Round 3 a = hh(a, b, c, d, k[5], 4, -378558); d = hh(d, a, b, c, k[8], 11, -2022574463); c = hh(c, d, a, b, k[11], 16, 1839030562); b = hh(b, c, d, a, k[14], 23, -35309556); a = hh(a, b, c, d, k[1], 4, -1530992060); d = hh(d, a, b, c, k[4], 11, 1272893353); c = hh(c, d, a, b, k[7], 16, -155497632); b = hh(b, c, d, a, k[10], 23, -1094730640); a = hh(a, b, c, d, k[13], 4, 681279174); d = hh(d, a, b, c, k[0], 11, -358537222); c = hh(c, d, a, b, k[3], 16, -722521979); b = hh(b, c, d, a, k[6], 23, 76029189); a = hh(a, b, c, d, k[9], 4, -640364487); d = hh(d, a, b, c, k[12], 11, -421815835); c = hh(c, d, a, b, k[15], 16, 530742520); b = hh(b, c, d, a, k[2], 23, -995338651); // Round 4 a = ii(a, b, c, d, k[0], 6, -198630844); d = ii(d, a, b, c, k[7], 10, 1126891415); c = ii(c, d, a, b, k[14], 15, -1416354905); b = ii(b, c, d, a, k[5], 21, -57434055); a = ii(a, b, c, d, k[12], 6, 1700485571); d = ii(d, a, b, c, k[3], 10, -1894986606); c = ii(c, d, a, b, k[10], 15, -1051523); b = ii(b, c, d, a, k[1], 21, -2054922799); a = ii(a, b, c, d, k[8], 6, 1873313359); d = ii(d, a, b, c, k[15], 10, -30611744); c = ii(c, d, a, b, k[6], 15, -1560198380); b = ii(b, c, d, a, k[13], 21, 1309151649); a = ii(a, b, c, d, k[4], 6, -145523070); d = ii(d, a, b, c, k[11], 10, -1120210379); c = ii(c, d, a, b, k[2], 15, 718787259); b = ii(b, c, d, a, k[9], 21, -343485551); x[0] = safeAdd32(a, x[0]); x[1] = safeAdd32(b, x[1]); x[2] = safeAdd32(c, x[2]); x[3] = safeAdd32(d, x[3]); } function cmn(q, a, b, x, s, t) { a = safeAdd32(safeAdd32(a, q), safeAdd32(x, t)); return safeAdd32(ROTR(32 - s, a), b); } function ff(a, b, c, d, x, s, t) { return cmn((b & c) | ((~b) & d), a, b, x, s, t); } function gg(a, b, c, d, x, s, t) { return cmn((b & d) | (c & (~d)), a, b, x, s, t); } function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); } function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | (~d)), a, b, x, s, t); } function processBlock(state, input, offset) { const chunk = new Int32Array(16); const dv = new DataView(input.buffer, input.byteOffset); for (let j = 0; j < 16; j++) { chunk[j] = dv.getUint32(offset + (j * 4), true); } md5cycle(state, chunk); } function md5(input) { // Convert string to Uint8Array if needed let data; if (typeof input === 'string') { data = new TextEncoder().encode(input); } else if (input instanceof Uint8Array) { data = input; } else { throw new Error('Input must be a string or Uint8Array'); } // Initialize hash values const state = new Int32Array([ 1732584193, // A -271733879, // B -1732584194, // C 271733878 // D ]); // Pre-processing: pad the input const originalLength = data.length; const paddedLength = Math.ceil((originalLength + 9) / 64) * 64; const padded = new Uint8Array(paddedLength); // Copy original data padded.set(data); // Append padding bits padded[originalLength] = 0x80; // Append original length in bits as little-endian 64-bit integer const bitLength = originalLength * 8; const dv = new DataView(padded.buffer); dv.setUint32(paddedLength - 8, bitLength, true); dv.setUint32(paddedLength - 4, 0, true); // Process each 64-byte chunk for (let i = 0; i < paddedLength; i += 64) { processBlock(state, padded, i); } // Convert state to bytes const result = new Uint8Array(16); const resultView = new DataView(result.buffer); for (let i = 0; i < 4; i++) { resultView.setInt32(i * 4, state[i], true); } // Convert to hex string return Array.from(result) .map(b => b.toString(16).padStart(2, '0')) .join(''); } function sha256(msgBytes, rounds = 64) { const K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, @@ -198,53 +187,43 @@ function sha256(msgBytes, rounds = 64) { 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; const H = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; const paddedLength = Math.ceil((msgBytes.length + 9) / 64) * 64; const paddedBytes = new Uint8Array(paddedLength); paddedBytes.set(msgBytes); paddedBytes[msgBytes.length] = 0x80; const msgLengthBits = msgBytes.length * 8; const dv = new DataView(paddedBytes.buffer); dv.setUint32(paddedLength - 8, Math.floor(msgLengthBits / Math.pow(2, 32)), false); dv.setUint32(paddedLength - 4, msgLengthBits & 0xffffffff, false); const N = paddedLength / 64; const M = new Array(N); for (let i = 0; i < N; i++) { M[i] = new Array(16); for (let j = 0; j < 16; j++) { M[i][j] = (paddedBytes[i * 64 + j * 4] << 24) | (paddedBytes[i * 64 + j * 4 + 1] << 16) | (paddedBytes[i * 64 + j * 4 + 2] << 8) | (paddedBytes[i * 64 + j * 4 + 3]); } } const W = new Array(64); let a, b, c, d, e, f, g, h; for (let i = 0; i < N; i++) { for (let t = 0; t < 16; t++) W[t] = M[i][t]; for (let t = 16; t < 64; t++) W[t] = (σ1(W[t - 2]) + W[t - 7] + σ0(W[t - 15]) + W[t - 16]) >>> 0; a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; for (let t = 0; t < rounds; t++) { const T1 = (h + Σ1(e) + Ch(e, f, g) + K[t] + W[t]) >>> 0; const T2 = (Σ0(a) + Maj(a, b, c)) >>> 0; @@ -258,7 +237,6 @@ function sha256(msgBytes, rounds = 64) { a = (T1 + T2) >>> 0; } H[0] = (H[0] + a) >>> 0; H[1] = (H[1] + b) >>> 0; H[2] = (H[2] + c) >>> 0; @@ -269,10 +247,8 @@ function sha256(msgBytes, rounds = 64) { H[7] = (H[7] + h) >>> 0; } return H.map(n => n.toString(16).padStart(8, '0')).join(''); function Σ0(x) { return ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x); } function Σ1(x) { return ROTR(6, x) ^ ROTR(11, x) ^ ROTR(25, x); } function σ0(x) { return ROTR(7, x) ^ ROTR(18, x) ^ (x >>> 3); } @@ -282,7 +258,6 @@ function sha256(msgBytes, rounds = 64) { } function hmac(key, message, hash, blockSize = 64) { function hexToBytes(hex) { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { @@ -291,15 +266,12 @@ function hmac(key, message, hash, blockSize = 64) { return bytes; } function computeBlockSizedKey(key, hash, blockSize) { let keyBytes = typeof key === 'string' ? new TextEncoder().encode(key) : key; if (keyBytes.length > blockSize) { const hashedKey = hash(keyBytes); keyBytes = hexToBytes(hashedKey); } if (keyBytes.length < blockSize) { const paddedKey = new Uint8Array(blockSize); paddedKey.set(keyBytes); @@ -308,23 +280,19 @@ function hmac(key, message, hash, blockSize = 64) { return keyBytes; } const blockSizedKey = computeBlockSizedKey(key, hash, blockSize); const oKeyPad = new Uint8Array(blockSize); const iKeyPad = new Uint8Array(blockSize); for (let i = 0; i < blockSize; i++) { oKeyPad[i] = blockSizedKey[i] ^ 0x5c; iKeyPad[i] = blockSizedKey[i] ^ 0x36; } const messageBytes = typeof message === 'string' ? new TextEncoder().encode(message) : message; const innerHashHex = hash(new Uint8Array([...iKeyPad, ...messageBytes])); const innerHashBytes = hexToBytes(innerHashHex); const hmacValue = hash(new Uint8Array([...oKeyPad, ...innerHashBytes])); -
Kreijstal revised this gist
Nov 13, 2024 . 1 changed file with 187 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,190 @@ function md5cycle(x, k) { var a = x[0], b = x[1], c = x[2], d = x[3]; a = ff(a, b, c, d, k[0], 7, -680876936); d = ff(d, a, b, c, k[1], 12, -389564586); c = ff(c, d, a, b, k[2], 17, 606105819); b = ff(b, c, d, a, k[3], 22, -1044525330); a = ff(a, b, c, d, k[4], 7, -176418897); d = ff(d, a, b, c, k[5], 12, 1200080426); c = ff(c, d, a, b, k[6], 17, -1473231341); b = ff(b, c, d, a, k[7], 22, -45705983); a = ff(a, b, c, d, k[8], 7, 1770035416); d = ff(d, a, b, c, k[9], 12, -1958414417); c = ff(c, d, a, b, k[10], 17, -42063); b = ff(b, c, d, a, k[11], 22, -1990404162); a = ff(a, b, c, d, k[12], 7, 1804603682); d = ff(d, a, b, c, k[13], 12, -40341101); c = ff(c, d, a, b, k[14], 17, -1502002290); b = ff(b, c, d, a, k[15], 22, 1236535329); a = gg(a, b, c, d, k[1], 5, -165796510); d = gg(d, a, b, c, k[6], 9, -1069501632); c = gg(c, d, a, b, k[11], 14, 643717713); b = gg(b, c, d, a, k[0], 20, -373897302); a = gg(a, b, c, d, k[5], 5, -701558691); d = gg(d, a, b, c, k[10], 9, 38016083); c = gg(c, d, a, b, k[15], 14, -660478335); b = gg(b, c, d, a, k[4], 20, -405537848); a = gg(a, b, c, d, k[9], 5, 568446438); d = gg(d, a, b, c, k[14], 9, -1019803690); c = gg(c, d, a, b, k[3], 14, -187363961); b = gg(b, c, d, a, k[8], 20, 1163531501); a = gg(a, b, c, d, k[13], 5, -1444681467); d = gg(d, a, b, c, k[2], 9, -51403784); c = gg(c, d, a, b, k[7], 14, 1735328473); b = gg(b, c, d, a, k[12], 20, -1926607734); a = hh(a, b, c, d, k[5], 4, -378558); d = hh(d, a, b, c, k[8], 11, -2022574463); c = hh(c, d, a, b, k[11], 16, 1839030562); b = hh(b, c, d, a, k[14], 23, -35309556); a = hh(a, b, c, d, k[1], 4, -1530992060); d = hh(d, a, b, c, k[4], 11, 1272893353); c = hh(c, d, a, b, k[7], 16, -155497632); b = hh(b, c, d, a, k[10], 23, -1094730640); a = hh(a, b, c, d, k[13], 4, 681279174); d = hh(d, a, b, c, k[0], 11, -358537222); c = hh(c, d, a, b, k[3], 16, -722521979); b = hh(b, c, d, a, k[6], 23, 76029189); a = hh(a, b, c, d, k[9], 4, -640364487); d = hh(d, a, b, c, k[12], 11, -421815835); c = hh(c, d, a, b, k[15], 16, 530742520); b = hh(b, c, d, a, k[2], 23, -995338651); a = ii(a, b, c, d, k[0], 6, -198630844); d = ii(d, a, b, c, k[7], 10, 1126891415); c = ii(c, d, a, b, k[14], 15, -1416354905); b = ii(b, c, d, a, k[5], 21, -57434055); a = ii(a, b, c, d, k[12], 6, 1700485571); d = ii(d, a, b, c, k[3], 10, -1894986606); c = ii(c, d, a, b, k[10], 15, -1051523); b = ii(b, c, d, a, k[1], 21, -2054922799); a = ii(a, b, c, d, k[8], 6, 1873313359); d = ii(d, a, b, c, k[15], 10, -30611744); c = ii(c, d, a, b, k[6], 15, -1560198380); b = ii(b, c, d, a, k[13], 21, 1309151649); a = ii(a, b, c, d, k[4], 6, -145523070); d = ii(d, a, b, c, k[11], 10, -1120210379); c = ii(c, d, a, b, k[2], 15, 718787259); b = ii(b, c, d, a, k[9], 21, -343485551); x[0] = add32(a, x[0]); x[1] = add32(b, x[1]); x[2] = add32(c, x[2]); x[3] = add32(d, x[3]); } function cmn(q, a, b, x, s, t) { a = add32(add32(a, q), add32(x, t)); return add32((a << s) | (a >>> (32 - s)), b); } function ff(a, b, c, d, x, s, t) { return cmn((b & c) | ((~b) & d), a, b, x, s, t); } function gg(a, b, c, d, x, s, t) { return cmn((b & d) | (c & (~d)), a, b, x, s, t); } function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); } function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | (~d)), a, b, x, s, t); } function md51(s) { txt = ''; var n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i; for (i=64; i<=s.length; i+=64) { md5cycle(state, md5blk(s.substring(i-64, i))); } s = s.substring(i-64); var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; for (i=0; i<s.length; i++) tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3); tail[i>>2] |= 0x80 << ((i%4) << 3); if (i > 55) { md5cycle(state, tail); for (i=0; i<16; i++) tail[i] = 0; } tail[14] = n*8; md5cycle(state, tail); return state; } /* there needs to be support for Unicode here, * unless we pretend that we can redefine the MD-5 * algorithm for multi-byte characters (perhaps * by adding every four 16-bit characters and * shortening the sum to 32 bits). Otherwise * I suggest performing MD-5 as if every character * was two bytes--e.g., 0040 0025 = @%--but then * how will an ordinary MD-5 sum be matched? * There is no way to standardize text to something * like UTF-8 before transformation; speed cost is * utterly prohibitive. The JavaScript standard * itself needs to look at this: it should start * providing access to strings as preformed UTF-8 * 8-bit unsigned value arrays. */ function md5blk(s) { /* I figured global was faster. */ var md5blks = [], i; /* Andy King said do it this way. */ for (i=0; i<64; i+=4) { md5blks[i>>2] = s.charCodeAt(i) + (s.charCodeAt(i+1) << 8) + (s.charCodeAt(i+2) << 16) + (s.charCodeAt(i+3) << 24); } return md5blks; } var hex_chr = '0123456789abcdef'.split(''); function rhex(n) { var s='', j=0; for(; j<4; j++) s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; return s; } function hex(x) { for (var i=0; i<x.length; i++) x[i] = rhex(x[i]); return x.join(''); } function md5(s) { return hex(md51(s)); } /* this function is much faster, so if possible we use it. Some IEs are the only ones I know of that need the idiotic second function, generated by an if clause. */ function add32(a, b) { return (a + b) & 0xFFFFFFFF; } if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') { function add32(x, y) { var lsw = (x & 0xFFFF) + (y & 0xFFFF), msw = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xFFFF); } } function sha256(msgBytes, rounds = 64) { // Constants [§4.2.2] const K = [ -
Kreijstal revised this gist
Nov 13, 2024 . 1 changed file with 51 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -92,4 +92,55 @@ function sha256(msgBytes, rounds = 64) { function σ1(x) { return ROTR(17, x) ^ ROTR(19, x) ^ (x >>> 10); } function Ch(x, y, z) { return (x & y) ^ (~x & z); } function Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } } function hmac(key, message, hash, blockSize = 64) { // Helper function to convert hex string to Uint8Array function hexToBytes(hex) { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16); } return bytes; } // Helper function to compute the block-sized key function computeBlockSizedKey(key, hash, blockSize) { let keyBytes = typeof key === 'string' ? new TextEncoder().encode(key) : key; // Keys longer than blockSize are shortened by hashing them if (keyBytes.length > blockSize) { const hashedKey = hash(keyBytes); keyBytes = hexToBytes(hashedKey); } // Keys shorter than blockSize are padded to blockSize by padding with zeros on the right if (keyBytes.length < blockSize) { const paddedKey = new Uint8Array(blockSize); paddedKey.set(keyBytes); return paddedKey; } return keyBytes; } // Compute the block-sized key const blockSizedKey = computeBlockSizedKey(key, hash, blockSize); // Create the outer and inner padded keys const oKeyPad = new Uint8Array(blockSize); const iKeyPad = new Uint8Array(blockSize); for (let i = 0; i < blockSize; i++) { oKeyPad[i] = blockSizedKey[i] ^ 0x5c; iKeyPad[i] = blockSizedKey[i] ^ 0x36; } // Convert message to Uint8Array if it's a string const messageBytes = typeof message === 'string' ? new TextEncoder().encode(message) : message; // Compute the HMAC const innerHashHex = hash(new Uint8Array([...iKeyPad, ...messageBytes])); const innerHashBytes = hexToBytes(innerHashHex); const hmacValue = hash(new Uint8Array([...oKeyPad, ...innerHashBytes])); return hmacValue; } -
Kreijstal revised this gist
Nov 13, 2024 . 1 changed file with 92 additions and 166 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,169 +1,95 @@ function sha256(msgBytes, rounds = 64) { // Constants [§4.2.2] const K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; // Initial hash value [§5.3.1] const H = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; // PREPROCESSING // Create a new array with padding const paddedLength = Math.ceil((msgBytes.length + 9) / 64) * 64; // +9 for 0x80 byte and 64-bit length const paddedBytes = new Uint8Array(paddedLength); paddedBytes.set(msgBytes); paddedBytes[msgBytes.length] = 0x80; // Add trailing '1' bit (+ 0's padding) // Add length (in bits) into final pair of 32-bit integers (big-endian) const msgLengthBits = msgBytes.length * 8; const dv = new DataView(paddedBytes.buffer); dv.setUint32(paddedLength - 8, Math.floor(msgLengthBits / Math.pow(2, 32)), false); // high-order bits dv.setUint32(paddedLength - 4, msgLengthBits & 0xffffffff, false); // low-order bits // Process the message in successive 512-bit (64-byte) chunks const N = paddedLength / 64; const M = new Array(N); for (let i = 0; i < N; i++) { M[i] = new Array(16); for (let j = 0; j < 16; j++) { M[i][j] = (paddedBytes[i * 64 + j * 4] << 24) | (paddedBytes[i * 64 + j * 4 + 1] << 16) | (paddedBytes[i * 64 + j * 4 + 2] << 8) | (paddedBytes[i * 64 + j * 4 + 3]); } } // HASH COMPUTATION [§6.1.2] const W = new Array(64); let a, b, c, d, e, f, g, h; for (let i = 0; i < N; i++) { // 1 - Prepare message schedule 'W' for (let t = 0; t < 16; t++) W[t] = M[i][t]; for (let t = 16; t < 64; t++) W[t] = (σ1(W[t - 2]) + W[t - 7] + σ0(W[t - 15]) + W[t - 16]) >>> 0; // 2 - Initialize working variables a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; // 3 - Main loop for (let t = 0; t < rounds; t++) { const T1 = (h + Σ1(e) + Ch(e, f, g) + K[t] + W[t]) >>> 0; const T2 = (Σ0(a) + Maj(a, b, c)) >>> 0; h = g; g = f; f = e; e = (d + T1) >>> 0; d = c; c = b; b = a; a = (T1 + T2) >>> 0; } // 4 - Compute the new intermediate hash value H[0] = (H[0] + a) >>> 0; H[1] = (H[1] + b) >>> 0; H[2] = (H[2] + c) >>> 0; H[3] = (H[3] + d) >>> 0; H[4] = (H[4] + e) >>> 0; H[5] = (H[5] + f) >>> 0; H[6] = (H[6] + g) >>> 0; H[7] = (H[7] + h) >>> 0; } // Convert the final hash to hex string return H.map(n => n.toString(16).padStart(8, '0')).join(''); function ROTR(n, x) { return (x >>> n) | (x << (32 - n)); } function Σ0(x) { return ROTR(2, x) ^ ROTR(13, x) ^ ROTR(22, x); } function Σ1(x) { return ROTR(6, x) ^ ROTR(11, x) ^ ROTR(25, x); } function σ0(x) { return ROTR(7, x) ^ ROTR(18, x) ^ (x >>> 3); } function σ1(x) { return ROTR(17, x) ^ ROTR(19, x) ^ (x >>> 10); } function Ch(x, y, z) { return (x & y) ^ (~x & z); } function Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } } -
rumkin created this gist
Feb 6, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,169 @@ ;(function(){ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* SHA-256 implementation in JavaScript (c) Chris Veness 2002-2014 / MIT Licence */ /* */ /* - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html */ /* http://csrc.nist.gov/groups/ST/toolkit/examples.html */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* jshint node:true *//* global define, escape, unescape */ 'use strict'; /** * SHA-256 hash function reference implementation. * * @namespace */ var Sha256 = {}; /** * Generates SHA-256 hash of string. * * @param {string} msg - String to be hashed * @returns {string} Hash of msg as hex character string */ Sha256.hash = function(msg) { // convert string to UTF-8, as SHA only deals with byte-streams msg = msg.utf8Encode(); // constants [§4.2.2] var K = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; // initial hash value [§5.3.1] var H = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; // PREPROCESSING msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1] // convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1] var l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length var N = Math.ceil(l/16); // number of 16-integer-blocks required to hold 'l' ints var M = new Array(N); for (var i=0; i<N; i++) { M[i] = new Array(16); for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) | (msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3)); } // note running off the end of msg is ok 'cos bitwise ops on NaN return 0 } // add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1] // note: most significant word would be (len-1)*8 >>> 32, but since JS converts // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14]); M[N-1][15] = ((msg.length-1)*8) & 0xffffffff; // HASH COMPUTATION [§6.1.2] var W = new Array(64); var a, b, c, d, e, f, g, h; for (var i=0; i<N; i++) { // 1 - prepare message schedule 'W' for (var t=0; t<16; t++) W[t] = M[i][t]; for (var t=16; t<64; t++) W[t] = (Sha256.σ1(W[t-2]) + W[t-7] + Sha256.σ0(W[t-15]) + W[t-16]) & 0xffffffff; // 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7]; // 3 - main loop (note 'addition modulo 2^32') for (var t=0; t<64; t++) { var T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t]; var T2 = Sha256.Σ0(a) + Sha256.Maj(a, b, c); h = g; g = f; f = e; e = (d + T1) & 0xffffffff; d = c; c = b; b = a; a = (T1 + T2) & 0xffffffff; } // 4 - compute the new intermediate hash value (note 'addition modulo 2^32') H[0] = (H[0]+a) & 0xffffffff; H[1] = (H[1]+b) & 0xffffffff; H[2] = (H[2]+c) & 0xffffffff; H[3] = (H[3]+d) & 0xffffffff; H[4] = (H[4]+e) & 0xffffffff; H[5] = (H[5]+f) & 0xffffffff; H[6] = (H[6]+g) & 0xffffffff; H[7] = (H[7]+h) & 0xffffffff; } return Sha256.toHexStr(H[0]) + Sha256.toHexStr(H[1]) + Sha256.toHexStr(H[2]) + Sha256.toHexStr(H[3]) + Sha256.toHexStr(H[4]) + Sha256.toHexStr(H[5]) + Sha256.toHexStr(H[6]) + Sha256.toHexStr(H[7]); }; /** * Rotates right (circular right shift) value x by n positions [§3.2.4]. * @private */ Sha256.ROTR = function(n, x) { return (x >>> n) | (x << (32-n)); }; /** * Logical functions [§4.1.2]. * @private */ Sha256.Σ0 = function(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); }; Sha256.Σ1 = function(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); }; Sha256.σ0 = function(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x>>>3); }; Sha256.σ1 = function(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); }; Sha256.Ch = function(x, y, z) { return (x & y) ^ (~x & z); }; Sha256.Maj = function(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); }; /** * Hexadecimal representation of a number. * @private */ Sha256.toHexStr = function(n) { // note can't use toString(16) as it is implementation-dependant, // and in IE returns signed numbers when used on full words var s="", v; for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); } return s; }; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** Extend String object with method to encode multi-byte string to utf8 * - monsur.hossa.in/2012/07/20/utf-8-in-javascript.html */ if (typeof String.prototype.utf8Encode == 'undefined') { String.prototype.utf8Encode = function() { return unescape( encodeURIComponent( this ) ); }; } /** Extend String object with method to decode utf8 string to multi-byte */ if (typeof String.prototype.utf8Decode == 'undefined') { String.prototype.utf8Decode = function() { try { return decodeURIComponent( escape( this ) ); } catch (e) { return this; // invalid UTF-8? return as-is } }; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (typeof module != 'undefined' && module.exports) module.exports = Sha256; // CommonJs export if (typeof define == 'function' && define.amd) define([], function() { return Sha256; }); // AMD if (typeof window !== 'undefined') window.Sha256 = Sha256; })();