UNPKG

cerceis-lib

Version:

Contains list of quality of life functions that is written in TypeScript and es6

189 lines (188 loc) 7.41 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Sha256 = void 0; const constants_js_1 = require("./constants.js"); const Sha256 = (inputStr) => { const _toBinary = (text) => { let rs = ""; for (let i = 0; i < text.length; i++) { rs += text[i].charCodeAt(0).toString(2).padStart(8, "0"); } return rs; }; //Shift right //Rotate right //XOR //ADD <= remember to keep it in 32 bit range const _rotr = (arr, attempt = 1) => { let tmp = [...arr]; for (let i = 0; i < attempt; i++) { tmp = [tmp.pop(), ...tmp]; } return tmp; }; const _shr = (arr, attempt = 1) => { let tmp = [...arr]; for (let i = 0; i < attempt; i++) { tmp.pop(); tmp.unshift("0"); } return tmp; }; const _xor = (arrA, arrB, arrC) => { const tmp = []; arrA.forEach((bit, index) => { tmp[index] = String(Number(bit) ^ Number(arrB[index]) ^ Number(arrC[index])); }); return tmp; }; const _add = (arrA, arrB) => { const tmp = []; const len = arrA.length; let extra = 0; for (let i = arrA.length - 1; i >= 0; i--) { const bitValue = Number(arrA[i]) + Number(arrB[i]) + extra; tmp[i] = bitValue > 1 ? String(bitValue - 2) : String(bitValue); extra = bitValue > 1 ? 1 : 0; } return tmp; }; /** * Functions * choice, given x,y,z. If x = 1 takes y, if x = 0 takes z * major, given x,y,z. If numbers of 1 > 0 then 1. else 0. */ const _choice = (arrA, arrB, arrC) => { let tmp = []; arrA.forEach((bit, index) => { tmp[index] = bit === "1" ? arrB[index] : arrC[index]; }); return tmp; }; const _major = (arrA, arrB, arrC) => { let tmp = []; arrA.forEach((bit, index) => { const val = bit + arrB[index] + arrC[index]; if (val === "000" || val === "001" || val === "010" || val === "100") tmp[index] = "0"; else if (val === "111" || val === "110" || val === "101" || val === "011") tmp[index] = "1"; }); return tmp; }; /** * Compound movements * sigZero = ROTR 7, ROTR 18, SHR 3, XOR * sigOne = ROTR 17, ROTR 19, SHR 10, XOR * uSigZero = ROTR 2, ROTR 13, ROTR 22, XOR * uSigOne = ROTR 6, ROTR 11, ROTR 25, XOR */ const _sigZero = (arr) => { const rotr7 = _rotr(arr, 7); const rotr18 = _rotr(arr, 18); const shr3 = _shr(arr, 3); return _xor(rotr7, rotr18, shr3); }; const _sigOne = (arr) => { const rotr17 = _rotr(arr, 17); const rotr19 = _rotr(arr, 19); const shr10 = _shr(arr, 10); return _xor(rotr17, rotr19, shr10); }; const _uSigZero = (arr) => { const rotr2 = _rotr(arr, 2); const rotr13 = _rotr(arr, 13); const rotr22 = _rotr(arr, 22); return _xor(rotr2, rotr13, rotr22); }; const _uSigOne = (arr) => { const rotr6 = _rotr(arr, 6); const rotr11 = _rotr(arr, 11); const rotr25 = _rotr(arr, 25); return _xor(rotr6, rotr11, rotr25); }; const shiftCompressionMap = (compressionMap) => { compressionMap["h"] = [...compressionMap["g"]]; compressionMap["g"] = [...compressionMap["f"]]; compressionMap["f"] = [...compressionMap["e"]]; compressionMap["e"] = [...compressionMap["d"]]; compressionMap["d"] = [...compressionMap["c"]]; compressionMap["c"] = [...compressionMap["b"]]; compressionMap["b"] = [...compressionMap["a"]]; compressionMap["a"] = []; }; /** * Structure will be: * The binary of the message + 1 as separator + padding of 0 until 448 bits + length of the message with start padding of 0. * End result will be total of 512 in length */ let messageBin = _toBinary(inputStr); const messageBlocks = []; const messageLengthBin = messageBin.length.toString(2).padStart(64, "0"); const blockCount = Math.ceil((messageBin.length + 1 + 64) / 512); const finalLength = blockCount * 512; /* messageBin += "1" //Separator messageBin = messageBin.padEnd(512 * blockCount - 64, "0") //padding of 0 until 448 bits messageBin += messageLengthBin //Remaining 64 with length of the message with start padding of 0. */ // 𝑘=512𝑖+447−𝑚 /** * k = paddings * i = blockCount * m = input length * Pre-processing (Padding): begin with the original message of length L bits append a single '1' bit append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512 append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits such that the bits in the message are L 1 00..<K 0's>..00 <L as 64 bit integer> = k*512 total bits */ messageBin += "1"; //Separator messageBin = messageBin.padEnd(finalLength - 64, "0"); //padding of 0 until 448 bits messageBin += messageLengthBin; //Remaining 64 with length of the message with start padding of 0. for (let i = 0; i < blockCount; i++) { let messageChunks = messageBin.slice(i * 512, i * 512 + 512); //Add padding to last block messageBlocks.push(messageChunks); } let finalCompression = Object.assign({}, constants_js_1.compressionHash); //message schedule messageBlocks.forEach((block, bi) => { let localCompression = Object.assign({}, finalCompression); const words = []; for (let i = 0; i < 16; i++) { words.push(block.slice(i * 32, i * 32 + 32).split("")); } //Words need to be 64 in length, so we gonna expand it //sigOne(-2) + (-7) + sigZero(-15) + (-16) while (words.length < 64) { words.push(_add(_add(_add(_sigOne(words[words.length - 2]), words[words.length - 7]), _sigZero(words[words.length - 15])), words[words.length - 16])); } //Compression /** * T1 = uSigOne(e) + choice(e,f,g) + h + K0 + W0 * T2 = uSigZero(a) + major(a,b,c) */ words.forEach((word, index) => { const t1 = _add(_add(_add(_add(_uSigOne(localCompression.e), _choice(localCompression.e, localCompression.f, localCompression.g)), localCompression.h), constants_js_1.primeConst[index]), word); const t2 = _add(_uSigZero(localCompression.a), _major(localCompression.a, localCompression.b, localCompression.c)); shiftCompressionMap(localCompression); localCompression.a = _add(t1, t2); localCompression.e = _add(localCompression.e, t1); }); for (let id in localCompression) { if (bi === 0) finalCompression[id] = _add(constants_js_1.compressionHash[id], localCompression[id]); else finalCompression[id] = _add(finalCompression[id], localCompression[id]); } }); let result = ""; for (let id in finalCompression) result += parseInt(finalCompression[id].join(""), 2).toString(16); return result; }; exports.Sha256 = Sha256;