* Hashes message using SHA-1 Cryptographic Hash Function * * @param {string} message - message to hash * @return {string} - message digest (hash value)
(message)
| 96 | * @return {string} - message digest (hash value) |
| 97 | */ |
| 98 | function SHA1(message) { |
| 99 | // main variables |
| 100 | let H0 = 0x67452301 |
| 101 | let H1 = 0xefcdab89 |
| 102 | let H2 = 0x98badcfe |
| 103 | let H3 = 0x10325476 |
| 104 | let H4 = 0xc3d2e1f0 |
| 105 | |
| 106 | // pre-process message and split into 512 bit chunks |
| 107 | const bits = preProcess(message) |
| 108 | const chunks = chunkify(bits, 512) |
| 109 | |
| 110 | chunks.forEach(function (chunk, i) { |
| 111 | // break each chunk into 16 32-bit words |
| 112 | const words = chunkify(chunk, 32) |
| 113 | |
| 114 | // extend 16 32-bit words to 80 32-bit words |
| 115 | for (let i = 16; i < 80; i++) { |
| 116 | const val = [words[i - 3], words[i - 8], words[i - 14], words[i - 16]] |
| 117 | .map((e) => parseInt(e, 2)) |
| 118 | .reduce((acc, curr) => curr ^ acc, 0) |
| 119 | const bin = (val >>> 0).toString(2) |
| 120 | const paddedBin = pad(bin, 32) |
| 121 | const word = rotateLeft(paddedBin, 1) |
| 122 | words.push(word) |
| 123 | } |
| 124 | |
| 125 | // initialize variables for this chunk |
| 126 | let [a, b, c, d, e] = [H0, H1, H2, H3, H4] |
| 127 | |
| 128 | for (let i = 0; i < 80; i++) { |
| 129 | let f, k |
| 130 | if (i < 20) { |
| 131 | f = (b & c) | (~b & d) |
| 132 | k = 0x5a827999 |
| 133 | } else if (i < 40) { |
| 134 | f = b ^ c ^ d |
| 135 | k = 0x6ed9eba1 |
| 136 | } else if (i < 60) { |
| 137 | f = (b & c) | (b & d) | (c & d) |
| 138 | k = 0x8f1bbcdc |
| 139 | } else { |
| 140 | f = b ^ c ^ d |
| 141 | k = 0xca62c1d6 |
| 142 | } |
| 143 | // make sure f is unsigned |
| 144 | f >>>= 0 |
| 145 | |
| 146 | const aRot = rotateLeft(pad(a.toString(2), 32), 5) |
| 147 | const aInt = parseInt(aRot, 2) >>> 0 |
| 148 | const wordInt = parseInt(words[i], 2) >>> 0 |
| 149 | const t = aInt + f + e + k + wordInt |
| 150 | e = d >>> 0 |
| 151 | d = c >>> 0 |
| 152 | const bRot = rotateLeft(pad(b.toString(2), 32), 30) |
| 153 | c = parseInt(bRot, 2) >>> 0 |
| 154 | b = a >>> 0 |
| 155 | a = t >>> 0 |
no test coverage detected