Rev 1417 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1417 | Rev 1419 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /** |
1 | /** |
2 | * [js-sha3]{@link https://github.com/emn178/js-sha3} |
2 | * [js-sha3]{@link https://github.com/emn178/js-sha3} |
3 | * |
3 | * |
4 | * @version 0.9.0 |
4 | * @version 0.9.2 |
5 | * @author Chen, Yi-Cyuan [emn178@gmail.com] |
5 | * @author Chen, Yi-Cyuan [emn178@gmail.com] |
6 | * @copyright Chen, Yi-Cyuan 2015-2023 |
6 | * @copyright Chen, Yi-Cyuan 2015-2023 |
7 | * @license MIT |
7 | * @license MIT |
8 | */ |
8 | */ |
9 | /*jslint bitwise: true */ |
9 | /*jslint bitwise: true */ |
Line 44... | Line 44... | ||
44 | var CSHAKE_BYTEPAD = { |
44 | var CSHAKE_BYTEPAD = { |
45 | '128': 168, |
45 | '128': 168, |
46 | '256': 136 |
46 | '256': 136 |
47 | }; |
47 | }; |
48 | 48 | ||
- | 49 | ||
49 | if (root.JS_SHA3_NO_NODE_JS || !Array.isArray) { |
50 | var isArray = root.JS_SHA3_NO_NODE_JS || !Array.isArray |
50 | Array.isArray = function (obj) { |
51 | ? function (obj) { |
51 | return Object.prototype.toString.call(obj) === '[object Array]'; |
52 | return Object.prototype.toString.call(obj) === '[object Array]'; |
52 | }; |
- | |
53 | } |
53 | } |
- | 54 | : Array.isArray; |
|
54 | 55 | ||
55 | if (ARRAY_BUFFER && (root.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) { |
56 | var isView = (ARRAY_BUFFER && (root.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) |
56 | ArrayBuffer.isView = function (obj) { |
57 | ? function (obj) { |
57 | return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; |
58 | return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer; |
- | 59 | } |
|
- | 60 | : ArrayBuffer.isView; |
|
- | 61 | ||
- | 62 | // [message: string, isString: bool] |
|
- | 63 | var formatMessage = function (message) { |
|
- | 64 | var type = typeof message; |
|
- | 65 | if (type === 'string') { |
|
- | 66 | return [message, true]; |
|
58 | }; |
67 | } |
- | 68 | if (type !== 'object' || message === null) { |
|
- | 69 | throw new Error(INPUT_ERROR); |
|
- | 70 | } |
|
- | 71 | if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { |
|
- | 72 | return [new Uint8Array(message), false]; |
|
- | 73 | } |
|
- | 74 | if (!isArray(message) && !isView(message)) { |
|
- | 75 | throw new Error(INPUT_ERROR); |
|
- | 76 | } |
|
- | 77 | return [message, false]; |
|
59 | } |
78 | } |
60 | 79 | ||
- | 80 | var empty = function (message) { |
|
- | 81 | return formatMessage(message)[0].length === 0; |
|
- | 82 | }; |
|
- | 83 | ||
61 | var createOutputMethod = function (bits, padding, outputType) { |
84 | var createOutputMethod = function (bits, padding, outputType) { |
62 | return function (message) { |
85 | return function (message) { |
63 | return new Keccak(bits, padding, bits).update(message)[outputType](); |
86 | return new Keccak(bits, padding, bits).update(message)[outputType](); |
64 | }; |
87 | }; |
65 | }; |
88 | }; |
Line 114... | Line 137... | ||
114 | 137 | ||
115 | var createCshakeMethod = function (bits, padding) { |
138 | var createCshakeMethod = function (bits, padding) { |
116 | var w = CSHAKE_BYTEPAD[bits]; |
139 | var w = CSHAKE_BYTEPAD[bits]; |
117 | var method = createCshakeOutputMethod(bits, padding, 'hex'); |
140 | var method = createCshakeOutputMethod(bits, padding, 'hex'); |
118 | method.create = function (outputBits, n, s) { |
141 | method.create = function (outputBits, n, s) { |
119 | if (!n && !s) { |
142 | if (empty(n) && empty(s)) { |
120 | return methods['shake' + bits].create(outputBits); |
143 | return methods['shake' + bits].create(outputBits); |
121 | } else { |
144 | } else { |
122 | return new Keccak(bits, padding, outputBits).bytepad([n, s], w); |
145 | return new Keccak(bits, padding, outputBits).bytepad([n, s], w); |
123 | } |
146 | } |
124 | }; |
147 | }; |
Line 186... | Line 209... | ||
186 | 209 | ||
187 | Keccak.prototype.update = function (message) { |
210 | Keccak.prototype.update = function (message) { |
188 | if (this.finalized) { |
211 | if (this.finalized) { |
189 | throw new Error(FINALIZE_ERROR); |
212 | throw new Error(FINALIZE_ERROR); |
190 | } |
213 | } |
191 | var notString, type = typeof message; |
214 | var result = formatMessage(message); |
192 | if (type !== 'string') { |
- | |
193 | if (type === 'object') { |
- | |
194 | if (message === null) { |
215 | message = result[0]; |
195 | throw new Error(INPUT_ERROR); |
- | |
196 | } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { |
- | |
197 | message = new Uint8Array(message); |
- | |
198 | } else if (!Array.isArray(message)) { |
- | |
199 | if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { |
- | |
200 | throw new Error(INPUT_ERROR); |
- | |
201 | } |
- | |
202 | } |
- | |
203 | } else { |
- | |
204 | throw new Error(INPUT_ERROR); |
- | |
205 | } |
- | |
206 | notString = true; |
216 | var isString = result[1]; |
207 | } |
- | |
208 | var blocks = this.blocks, byteCount = this.byteCount, length = message.length, |
217 | var blocks = this.blocks, byteCount = this.byteCount, length = message.length, |
209 | blockCount = this.blockCount, index = 0, s = this.s, i, code; |
218 | blockCount = this.blockCount, index = 0, s = this.s, i, code; |
210 | 219 | ||
211 | while (index < length) { |
220 | while (index < length) { |
212 | if (this.reset) { |
221 | if (this.reset) { |
Line 214... | Line 223... | ||
214 | blocks[0] = this.block; |
223 | blocks[0] = this.block; |
215 | for (i = 1; i < blockCount + 1; ++i) { |
224 | for (i = 1; i < blockCount + 1; ++i) { |
216 | blocks[i] = 0; |
225 | blocks[i] = 0; |
217 | } |
226 | } |
218 | } |
227 | } |
219 | if (notString) { |
228 | if (isString) { |
220 | for (i = this.start; index < length && i < byteCount; ++index) { |
- | |
221 | blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; |
- | |
222 | } |
- | |
223 | } else { |
- | |
224 | for (i = this.start; index < length && i < byteCount; ++index) { |
229 | for (i = this.start; index < length && i < byteCount; ++index) { |
225 | code = message.charCodeAt(index); |
230 | code = message.charCodeAt(index); |
226 | if (code < 0x80) { |
231 | if (code < 0x80) { |
227 | blocks[i >> 2] |= code << SHIFT[i++ & 3]; |
232 | blocks[i >> 2] |= code << SHIFT[i++ & 3]; |
228 | } else if (code < 0x800) { |
233 | } else if (code < 0x800) { |
Line 238... | Line 243... | ||
238 | blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; |
243 | blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3]; |
239 | blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; |
244 | blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3]; |
240 | blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; |
245 | blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3]; |
241 | } |
246 | } |
242 | } |
247 | } |
- | 248 | } else { |
|
- | 249 | for (i = this.start; index < length && i < byteCount; ++index) { |
|
- | 250 | blocks[i >> 2] |= message[index] << SHIFT[i++ & 3]; |
|
- | 251 | } |
|
243 | } |
252 | } |
244 | this.lastByteIndex = i; |
253 | this.lastByteIndex = i; |
245 | if (i >= byteCount) { |
254 | if (i >= byteCount) { |
246 | this.start = i - byteCount; |
255 | this.start = i - byteCount; |
247 | this.block = blocks[blockCount]; |
256 | this.block = blocks[blockCount]; |
Line 276... | Line 285... | ||
276 | this.update(bytes); |
285 | this.update(bytes); |
277 | return bytes.length; |
286 | return bytes.length; |
278 | }; |
287 | }; |
279 | 288 | ||
280 | Keccak.prototype.encodeString = function (str) { |
289 | Keccak.prototype.encodeString = function (str) { |
281 | var notString, type = typeof str; |
- | |
282 | if (type !== 'string') { |
- | |
283 | if (type === 'object') { |
- | |
284 | if (str === null) { |
- | |
285 | throw new Error(INPUT_ERROR); |
- | |
286 | } else if (ARRAY_BUFFER && str.constructor === ArrayBuffer) { |
- | |
287 | str = new Uint8Array(str); |
290 | var result = formatMessage(str); |
288 | } else if (!Array.isArray(str)) { |
- | |
289 | if (!ARRAY_BUFFER || !ArrayBuffer.isView(str)) { |
- | |
290 | throw new Error(INPUT_ERROR); |
- | |
291 | } |
- | |
292 | } |
- | |
293 | } else { |
291 | str = result[0]; |
294 | throw new Error(INPUT_ERROR); |
- | |
295 | } |
- | |
296 | notString = true; |
292 | var isString = result[1]; |
297 | } |
- | |
298 | var bytes = 0, length = str.length; |
293 | var bytes = 0, length = str.length; |
299 | if (notString) { |
294 | if (isString) { |
300 | bytes = length; |
- | |
301 | } else { |
- | |
302 | for (var i = 0; i < str.length; ++i) { |
295 | for (var i = 0; i < str.length; ++i) { |
303 | var code = str.charCodeAt(i); |
296 | var code = str.charCodeAt(i); |
304 | if (code < 0x80) { |
297 | if (code < 0x80) { |
305 | bytes += 1; |
298 | bytes += 1; |
306 | } else if (code < 0x800) { |
299 | } else if (code < 0x800) { |
Line 310... | Line 303... | ||
310 | } else { |
303 | } else { |
311 | code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff)); |
304 | code = 0x10000 + (((code & 0x3ff) << 10) | (str.charCodeAt(++i) & 0x3ff)); |
312 | bytes += 4; |
305 | bytes += 4; |
313 | } |
306 | } |
314 | } |
307 | } |
- | 308 | } else { |
|
- | 309 | bytes = length; |
|
315 | } |
310 | } |
316 | bytes += this.encode(bytes * 8); |
311 | bytes += this.encode(bytes * 8); |
317 | this.update(str); |
312 | this.update(str); |
318 | return bytes; |
313 | return bytes; |
319 | }; |
314 | }; |