UNPKG

configcat-common

Version:

ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.

191 lines (190 loc) 7.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sha256 = exports.sha1 = void 0; var Utils_1 = require("./Utils"); function sha1(msg) { function rotate_left(n, s) { var t4 = (n << s) | (n >>> (32 - s)); return t4; } ; var blockstart; var i, j; var W = new Array(80); var H0 = 0x67452301; var H1 = 0xEFCDAB89; var H2 = 0x98BADCFE; var H3 = 0x10325476; var H4 = 0xC3D2E1F0; var A, B, C, D, E; var temp; msg = Utils_1.utf8Encode(msg); var msg_len = msg.length; var word_array = new Array(); for (i = 0; i < msg_len - 3; i += 4) { j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 | msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3); word_array.push(j); } switch (msg_len % 4) { case 0: i = 0x080000000; break; case 1: i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000; break; case 2: i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000; break; case 3: i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80; break; } word_array.push(i); while ((word_array.length % 16) != 14) word_array.push(0); word_array.push(msg_len >>> 29); word_array.push((msg_len << 3) & 0x0ffffffff); for (blockstart = 0; blockstart < word_array.length; blockstart += 16) { for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i]; for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); A = H0; B = H1; C = H2; D = H3; E = H4; for (i = 0; i <= 19; i++) { temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff; E = D; D = C; C = rotate_left(B, 30); B = A; A = temp; } for (i = 20; i <= 39; i++) { temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff; E = D; D = C; C = rotate_left(B, 30); B = A; A = temp; } for (i = 40; i <= 59; i++) { temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff; E = D; D = C; C = rotate_left(B, 30); B = A; A = temp; } for (i = 60; i <= 79; i++) { temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff; E = D; D = C; C = rotate_left(B, 30); B = A; A = temp; } H0 = (H0 + A) & 0x0ffffffff; H1 = (H1 + B) & 0x0ffffffff; H2 = (H2 + C) & 0x0ffffffff; H3 = (H3 + D) & 0x0ffffffff; H4 = (H4 + E) & 0x0ffffffff; } return toHexString([H0, H1, H2, H3, H4]); } exports.sha1 = sha1; // Based on: https://stackoverflow.com/a/59777755/8656352 function sha256(msgUtf8) { function rightRotate(value, amount) { return (value >>> amount) | (value << (32 - amount)); } ; var lengthProperty = "length"; var mathPow = Math.pow; var maxWord = mathPow(2, 32); var i, j; // Used as a counter across the whole file var precomputedData = sha256; var hash = precomputedData.h; var k = precomputedData.k; if (!k) { // Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes // (we actually calculate the first 64, but extra values are just ignored) hash = []; // Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes k = []; var isComposite = {}; for (var candidate = 2, primeCounter = 0; primeCounter < 64; candidate++) { if (!isComposite[candidate]) { for (i = 0; i < 313; i += candidate) { isComposite[i] = candidate; } hash[primeCounter] = (mathPow(candidate, .5) * maxWord) | 0; k[primeCounter++] = (mathPow(candidate, 1 / 3) * maxWord) | 0; } } precomputedData.h = hash = hash.slice(0, 8); precomputedData.k = k; } var asciiBitLength = msgUtf8[lengthProperty] * 8; msgUtf8 += '\x80'; // Append Ƈ' bit (plus zero padding) var words = []; while (msgUtf8[lengthProperty] % 64 - 56) msgUtf8 += '\x00'; // More zero padding for (i = 0; i < msgUtf8[lengthProperty]; i++) { j = msgUtf8.charCodeAt(i); words[i >> 2] |= j << ((3 - i) % 4) * 8; } words[words[lengthProperty]] = ((asciiBitLength / maxWord) | 0); words[words[lengthProperty]] = (asciiBitLength); // process each chunk for (j = 0; j < words[lengthProperty];) { var w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration var oldHash = hash; // This is now the undefinedworking hash", often labelled as variables a...g // (we have to truncate as well, otherwise extra entries at the end accumulate hash = hash.slice(0, 8); for (i = 0; i < 64; i++) { // Expand the message into 64 words // Used below if var w15 = w[i - 15], w2 = w[i - 2]; // Iterate var a = hash[0], e = hash[4]; var temp1 = hash[7] + (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1 + ((e & hash[5]) ^ ((~e) & hash[6])) // ch + k[i] // Expand the message schedule if needed + (w[i] = (i < 16) ? w[i] : (w[i - 16] + (rightRotate(w15, 7) ^ rightRotate(w15, 18) ^ (w15 >>> 3)) // s0 + w[i - 7] + (rightRotate(w2, 17) ^ rightRotate(w2, 19) ^ (w2 >>> 10)) // s1 ) | 0); // This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0 + ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2])); // maj hash = [(temp1 + temp2) | 0].concat(hash); // We don't bother trimming off the extra ones, they're harmless as long as we're truncating when we do the slice() hash[4] = (hash[4] + temp1) | 0; } for (i = 0; i < 8; i++) { hash[i] = (hash[i] + oldHash[i]) | 0; } } return toHexString(hash, 8); } exports.sha256 = sha256; function toHexString(int32Array, count) { var hexDigits = "0123456789abcdef"; var result = ""; count !== null && count !== void 0 ? count : (count = int32Array.length); for (var i = 0; i < count; i++) { for (var j = 3; j >= 0; j--) { var b = (int32Array[i] >> (j << 3)) & 0xFF; result += hexDigits[b >> 4]; result += hexDigits[b & 0xF]; } } return result; }