source: trip-planner-front/node_modules/node-forge/lib/sha512.js@ 1ad8e64

Last change on this file since 1ad8e64 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 16.7 KB
Line 
1/**
2 * Secure Hash Algorithm with a 1024-bit block size implementation.
3 *
4 * This includes: SHA-512, SHA-384, SHA-512/224, and SHA-512/256. For
5 * SHA-256 (block size 512 bits), see sha256.js.
6 *
7 * See FIPS 180-4 for details.
8 *
9 * @author Dave Longley
10 *
11 * Copyright (c) 2014-2015 Digital Bazaar, Inc.
12 */
13var forge = require('./forge');
14require('./md');
15require('./util');
16
17var sha512 = module.exports = forge.sha512 = forge.sha512 || {};
18
19// SHA-512
20forge.md.sha512 = forge.md.algorithms.sha512 = sha512;
21
22// SHA-384
23var sha384 = forge.sha384 = forge.sha512.sha384 = forge.sha512.sha384 || {};
24sha384.create = function() {
25 return sha512.create('SHA-384');
26};
27forge.md.sha384 = forge.md.algorithms.sha384 = sha384;
28
29// SHA-512/256
30forge.sha512.sha256 = forge.sha512.sha256 || {
31 create: function() {
32 return sha512.create('SHA-512/256');
33 }
34};
35forge.md['sha512/256'] = forge.md.algorithms['sha512/256'] =
36 forge.sha512.sha256;
37
38// SHA-512/224
39forge.sha512.sha224 = forge.sha512.sha224 || {
40 create: function() {
41 return sha512.create('SHA-512/224');
42 }
43};
44forge.md['sha512/224'] = forge.md.algorithms['sha512/224'] =
45 forge.sha512.sha224;
46
47/**
48 * Creates a SHA-2 message digest object.
49 *
50 * @param algorithm the algorithm to use (SHA-512, SHA-384, SHA-512/224,
51 * SHA-512/256).
52 *
53 * @return a message digest object.
54 */
55sha512.create = function(algorithm) {
56 // do initialization as necessary
57 if(!_initialized) {
58 _init();
59 }
60
61 if(typeof algorithm === 'undefined') {
62 algorithm = 'SHA-512';
63 }
64
65 if(!(algorithm in _states)) {
66 throw new Error('Invalid SHA-512 algorithm: ' + algorithm);
67 }
68
69 // SHA-512 state contains eight 64-bit integers (each as two 32-bit ints)
70 var _state = _states[algorithm];
71 var _h = null;
72
73 // input buffer
74 var _input = forge.util.createBuffer();
75
76 // used for 64-bit word storage
77 var _w = new Array(80);
78 for(var wi = 0; wi < 80; ++wi) {
79 _w[wi] = new Array(2);
80 }
81
82 // determine digest length by algorithm name (default)
83 var digestLength = 64;
84 switch(algorithm) {
85 case 'SHA-384':
86 digestLength = 48;
87 break;
88 case 'SHA-512/256':
89 digestLength = 32;
90 break;
91 case 'SHA-512/224':
92 digestLength = 28;
93 break;
94 }
95
96 // message digest object
97 var md = {
98 // SHA-512 => sha512
99 algorithm: algorithm.replace('-', '').toLowerCase(),
100 blockLength: 128,
101 digestLength: digestLength,
102 // 56-bit length of message so far (does not including padding)
103 messageLength: 0,
104 // true message length
105 fullMessageLength: null,
106 // size of message length in bytes
107 messageLengthSize: 16
108 };
109
110 /**
111 * Starts the digest.
112 *
113 * @return this digest object.
114 */
115 md.start = function() {
116 // up to 56-bit message length for convenience
117 md.messageLength = 0;
118
119 // full message length (set md.messageLength128 for backwards-compatibility)
120 md.fullMessageLength = md.messageLength128 = [];
121 var int32s = md.messageLengthSize / 4;
122 for(var i = 0; i < int32s; ++i) {
123 md.fullMessageLength.push(0);
124 }
125 _input = forge.util.createBuffer();
126 _h = new Array(_state.length);
127 for(var i = 0; i < _state.length; ++i) {
128 _h[i] = _state[i].slice(0);
129 }
130 return md;
131 };
132 // start digest automatically for first time
133 md.start();
134
135 /**
136 * Updates the digest with the given message input. The given input can
137 * treated as raw input (no encoding will be applied) or an encoding of
138 * 'utf8' maybe given to encode the input using UTF-8.
139 *
140 * @param msg the message input to update with.
141 * @param encoding the encoding to use (default: 'raw', other: 'utf8').
142 *
143 * @return this digest object.
144 */
145 md.update = function(msg, encoding) {
146 if(encoding === 'utf8') {
147 msg = forge.util.encodeUtf8(msg);
148 }
149
150 // update message length
151 var len = msg.length;
152 md.messageLength += len;
153 len = [(len / 0x100000000) >>> 0, len >>> 0];
154 for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
155 md.fullMessageLength[i] += len[1];
156 len[1] = len[0] + ((md.fullMessageLength[i] / 0x100000000) >>> 0);
157 md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
158 len[0] = ((len[1] / 0x100000000) >>> 0);
159 }
160
161 // add bytes to input buffer
162 _input.putBytes(msg);
163
164 // process bytes
165 _update(_h, _w, _input);
166
167 // compact input buffer every 2K or if empty
168 if(_input.read > 2048 || _input.length() === 0) {
169 _input.compact();
170 }
171
172 return md;
173 };
174
175 /**
176 * Produces the digest.
177 *
178 * @return a byte buffer containing the digest value.
179 */
180 md.digest = function() {
181 /* Note: Here we copy the remaining bytes in the input buffer and
182 add the appropriate SHA-512 padding. Then we do the final update
183 on a copy of the state so that if the user wants to get
184 intermediate digests they can do so. */
185
186 /* Determine the number of bytes that must be added to the message
187 to ensure its length is congruent to 896 mod 1024. In other words,
188 the data to be digested must be a multiple of 1024 bits (or 128 bytes).
189 This data includes the message, some padding, and the length of the
190 message. Since the length of the message will be encoded as 16 bytes (128
191 bits), that means that the last segment of the data must have 112 bytes
192 (896 bits) of message and padding. Therefore, the length of the message
193 plus the padding must be congruent to 896 mod 1024 because
194 1024 - 128 = 896.
195
196 In order to fill up the message length it must be filled with
197 padding that begins with 1 bit followed by all 0 bits. Padding
198 must *always* be present, so if the message length is already
199 congruent to 896 mod 1024, then 1024 padding bits must be added. */
200
201 var finalBlock = forge.util.createBuffer();
202 finalBlock.putBytes(_input.bytes());
203
204 // compute remaining size to be digested (include message length size)
205 var remaining = (
206 md.fullMessageLength[md.fullMessageLength.length - 1] +
207 md.messageLengthSize);
208
209 // add padding for overflow blockSize - overflow
210 // _padding starts with 1 byte with first bit is set (byte value 128), then
211 // there may be up to (blockSize - 1) other pad bytes
212 var overflow = remaining & (md.blockLength - 1);
213 finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
214
215 // serialize message length in bits in big-endian order; since length
216 // is stored in bytes we multiply by 8 and add carry from next int
217 var next, carry;
218 var bits = md.fullMessageLength[0] * 8;
219 for(var i = 0; i < md.fullMessageLength.length - 1; ++i) {
220 next = md.fullMessageLength[i + 1] * 8;
221 carry = (next / 0x100000000) >>> 0;
222 bits += carry;
223 finalBlock.putInt32(bits >>> 0);
224 bits = next >>> 0;
225 }
226 finalBlock.putInt32(bits);
227
228 var h = new Array(_h.length);
229 for(var i = 0; i < _h.length; ++i) {
230 h[i] = _h[i].slice(0);
231 }
232 _update(h, _w, finalBlock);
233 var rval = forge.util.createBuffer();
234 var hlen;
235 if(algorithm === 'SHA-512') {
236 hlen = h.length;
237 } else if(algorithm === 'SHA-384') {
238 hlen = h.length - 2;
239 } else {
240 hlen = h.length - 4;
241 }
242 for(var i = 0; i < hlen; ++i) {
243 rval.putInt32(h[i][0]);
244 if(i !== hlen - 1 || algorithm !== 'SHA-512/224') {
245 rval.putInt32(h[i][1]);
246 }
247 }
248 return rval;
249 };
250
251 return md;
252};
253
254// sha-512 padding bytes not initialized yet
255var _padding = null;
256var _initialized = false;
257
258// table of constants
259var _k = null;
260
261// initial hash states
262var _states = null;
263
264/**
265 * Initializes the constant tables.
266 */
267function _init() {
268 // create padding
269 _padding = String.fromCharCode(128);
270 _padding += forge.util.fillString(String.fromCharCode(0x00), 128);
271
272 // create K table for SHA-512
273 _k = [
274 [0x428a2f98, 0xd728ae22], [0x71374491, 0x23ef65cd],
275 [0xb5c0fbcf, 0xec4d3b2f], [0xe9b5dba5, 0x8189dbbc],
276 [0x3956c25b, 0xf348b538], [0x59f111f1, 0xb605d019],
277 [0x923f82a4, 0xaf194f9b], [0xab1c5ed5, 0xda6d8118],
278 [0xd807aa98, 0xa3030242], [0x12835b01, 0x45706fbe],
279 [0x243185be, 0x4ee4b28c], [0x550c7dc3, 0xd5ffb4e2],
280 [0x72be5d74, 0xf27b896f], [0x80deb1fe, 0x3b1696b1],
281 [0x9bdc06a7, 0x25c71235], [0xc19bf174, 0xcf692694],
282 [0xe49b69c1, 0x9ef14ad2], [0xefbe4786, 0x384f25e3],
283 [0x0fc19dc6, 0x8b8cd5b5], [0x240ca1cc, 0x77ac9c65],
284 [0x2de92c6f, 0x592b0275], [0x4a7484aa, 0x6ea6e483],
285 [0x5cb0a9dc, 0xbd41fbd4], [0x76f988da, 0x831153b5],
286 [0x983e5152, 0xee66dfab], [0xa831c66d, 0x2db43210],
287 [0xb00327c8, 0x98fb213f], [0xbf597fc7, 0xbeef0ee4],
288 [0xc6e00bf3, 0x3da88fc2], [0xd5a79147, 0x930aa725],
289 [0x06ca6351, 0xe003826f], [0x14292967, 0x0a0e6e70],
290 [0x27b70a85, 0x46d22ffc], [0x2e1b2138, 0x5c26c926],
291 [0x4d2c6dfc, 0x5ac42aed], [0x53380d13, 0x9d95b3df],
292 [0x650a7354, 0x8baf63de], [0x766a0abb, 0x3c77b2a8],
293 [0x81c2c92e, 0x47edaee6], [0x92722c85, 0x1482353b],
294 [0xa2bfe8a1, 0x4cf10364], [0xa81a664b, 0xbc423001],
295 [0xc24b8b70, 0xd0f89791], [0xc76c51a3, 0x0654be30],
296 [0xd192e819, 0xd6ef5218], [0xd6990624, 0x5565a910],
297 [0xf40e3585, 0x5771202a], [0x106aa070, 0x32bbd1b8],
298 [0x19a4c116, 0xb8d2d0c8], [0x1e376c08, 0x5141ab53],
299 [0x2748774c, 0xdf8eeb99], [0x34b0bcb5, 0xe19b48a8],
300 [0x391c0cb3, 0xc5c95a63], [0x4ed8aa4a, 0xe3418acb],
301 [0x5b9cca4f, 0x7763e373], [0x682e6ff3, 0xd6b2b8a3],
302 [0x748f82ee, 0x5defb2fc], [0x78a5636f, 0x43172f60],
303 [0x84c87814, 0xa1f0ab72], [0x8cc70208, 0x1a6439ec],
304 [0x90befffa, 0x23631e28], [0xa4506ceb, 0xde82bde9],
305 [0xbef9a3f7, 0xb2c67915], [0xc67178f2, 0xe372532b],
306 [0xca273ece, 0xea26619c], [0xd186b8c7, 0x21c0c207],
307 [0xeada7dd6, 0xcde0eb1e], [0xf57d4f7f, 0xee6ed178],
308 [0x06f067aa, 0x72176fba], [0x0a637dc5, 0xa2c898a6],
309 [0x113f9804, 0xbef90dae], [0x1b710b35, 0x131c471b],
310 [0x28db77f5, 0x23047d84], [0x32caab7b, 0x40c72493],
311 [0x3c9ebe0a, 0x15c9bebc], [0x431d67c4, 0x9c100d4c],
312 [0x4cc5d4be, 0xcb3e42b6], [0x597f299c, 0xfc657e2a],
313 [0x5fcb6fab, 0x3ad6faec], [0x6c44198c, 0x4a475817]
314 ];
315
316 // initial hash states
317 _states = {};
318 _states['SHA-512'] = [
319 [0x6a09e667, 0xf3bcc908],
320 [0xbb67ae85, 0x84caa73b],
321 [0x3c6ef372, 0xfe94f82b],
322 [0xa54ff53a, 0x5f1d36f1],
323 [0x510e527f, 0xade682d1],
324 [0x9b05688c, 0x2b3e6c1f],
325 [0x1f83d9ab, 0xfb41bd6b],
326 [0x5be0cd19, 0x137e2179]
327 ];
328 _states['SHA-384'] = [
329 [0xcbbb9d5d, 0xc1059ed8],
330 [0x629a292a, 0x367cd507],
331 [0x9159015a, 0x3070dd17],
332 [0x152fecd8, 0xf70e5939],
333 [0x67332667, 0xffc00b31],
334 [0x8eb44a87, 0x68581511],
335 [0xdb0c2e0d, 0x64f98fa7],
336 [0x47b5481d, 0xbefa4fa4]
337 ];
338 _states['SHA-512/256'] = [
339 [0x22312194, 0xFC2BF72C],
340 [0x9F555FA3, 0xC84C64C2],
341 [0x2393B86B, 0x6F53B151],
342 [0x96387719, 0x5940EABD],
343 [0x96283EE2, 0xA88EFFE3],
344 [0xBE5E1E25, 0x53863992],
345 [0x2B0199FC, 0x2C85B8AA],
346 [0x0EB72DDC, 0x81C52CA2]
347 ];
348 _states['SHA-512/224'] = [
349 [0x8C3D37C8, 0x19544DA2],
350 [0x73E19966, 0x89DCD4D6],
351 [0x1DFAB7AE, 0x32FF9C82],
352 [0x679DD514, 0x582F9FCF],
353 [0x0F6D2B69, 0x7BD44DA8],
354 [0x77E36F73, 0x04C48942],
355 [0x3F9D85A8, 0x6A1D36C8],
356 [0x1112E6AD, 0x91D692A1]
357 ];
358
359 // now initialized
360 _initialized = true;
361}
362
363/**
364 * Updates a SHA-512 state with the given byte buffer.
365 *
366 * @param s the SHA-512 state to update.
367 * @param w the array to use to store words.
368 * @param bytes the byte buffer to update with.
369 */
370function _update(s, w, bytes) {
371 // consume 512 bit (128 byte) chunks
372 var t1_hi, t1_lo;
373 var t2_hi, t2_lo;
374 var s0_hi, s0_lo;
375 var s1_hi, s1_lo;
376 var ch_hi, ch_lo;
377 var maj_hi, maj_lo;
378 var a_hi, a_lo;
379 var b_hi, b_lo;
380 var c_hi, c_lo;
381 var d_hi, d_lo;
382 var e_hi, e_lo;
383 var f_hi, f_lo;
384 var g_hi, g_lo;
385 var h_hi, h_lo;
386 var i, hi, lo, w2, w7, w15, w16;
387 var len = bytes.length();
388 while(len >= 128) {
389 // the w array will be populated with sixteen 64-bit big-endian words
390 // and then extended into 64 64-bit words according to SHA-512
391 for(i = 0; i < 16; ++i) {
392 w[i][0] = bytes.getInt32() >>> 0;
393 w[i][1] = bytes.getInt32() >>> 0;
394 }
395 for(; i < 80; ++i) {
396 // for word 2 words ago: ROTR 19(x) ^ ROTR 61(x) ^ SHR 6(x)
397 w2 = w[i - 2];
398 hi = w2[0];
399 lo = w2[1];
400
401 // high bits
402 t1_hi = (
403 ((hi >>> 19) | (lo << 13)) ^ // ROTR 19
404 ((lo >>> 29) | (hi << 3)) ^ // ROTR 61/(swap + ROTR 29)
405 (hi >>> 6)) >>> 0; // SHR 6
406 // low bits
407 t1_lo = (
408 ((hi << 13) | (lo >>> 19)) ^ // ROTR 19
409 ((lo << 3) | (hi >>> 29)) ^ // ROTR 61/(swap + ROTR 29)
410 ((hi << 26) | (lo >>> 6))) >>> 0; // SHR 6
411
412 // for word 15 words ago: ROTR 1(x) ^ ROTR 8(x) ^ SHR 7(x)
413 w15 = w[i - 15];
414 hi = w15[0];
415 lo = w15[1];
416
417 // high bits
418 t2_hi = (
419 ((hi >>> 1) | (lo << 31)) ^ // ROTR 1
420 ((hi >>> 8) | (lo << 24)) ^ // ROTR 8
421 (hi >>> 7)) >>> 0; // SHR 7
422 // low bits
423 t2_lo = (
424 ((hi << 31) | (lo >>> 1)) ^ // ROTR 1
425 ((hi << 24) | (lo >>> 8)) ^ // ROTR 8
426 ((hi << 25) | (lo >>> 7))) >>> 0; // SHR 7
427
428 // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^64 (carry lo overflow)
429 w7 = w[i - 7];
430 w16 = w[i - 16];
431 lo = (t1_lo + w7[1] + t2_lo + w16[1]);
432 w[i][0] = (t1_hi + w7[0] + t2_hi + w16[0] +
433 ((lo / 0x100000000) >>> 0)) >>> 0;
434 w[i][1] = lo >>> 0;
435 }
436
437 // initialize hash value for this chunk
438 a_hi = s[0][0];
439 a_lo = s[0][1];
440 b_hi = s[1][0];
441 b_lo = s[1][1];
442 c_hi = s[2][0];
443 c_lo = s[2][1];
444 d_hi = s[3][0];
445 d_lo = s[3][1];
446 e_hi = s[4][0];
447 e_lo = s[4][1];
448 f_hi = s[5][0];
449 f_lo = s[5][1];
450 g_hi = s[6][0];
451 g_lo = s[6][1];
452 h_hi = s[7][0];
453 h_lo = s[7][1];
454
455 // round function
456 for(i = 0; i < 80; ++i) {
457 // Sum1(e) = ROTR 14(e) ^ ROTR 18(e) ^ ROTR 41(e)
458 s1_hi = (
459 ((e_hi >>> 14) | (e_lo << 18)) ^ // ROTR 14
460 ((e_hi >>> 18) | (e_lo << 14)) ^ // ROTR 18
461 ((e_lo >>> 9) | (e_hi << 23))) >>> 0; // ROTR 41/(swap + ROTR 9)
462 s1_lo = (
463 ((e_hi << 18) | (e_lo >>> 14)) ^ // ROTR 14
464 ((e_hi << 14) | (e_lo >>> 18)) ^ // ROTR 18
465 ((e_lo << 23) | (e_hi >>> 9))) >>> 0; // ROTR 41/(swap + ROTR 9)
466
467 // Ch(e, f, g) (optimized the same way as SHA-1)
468 ch_hi = (g_hi ^ (e_hi & (f_hi ^ g_hi))) >>> 0;
469 ch_lo = (g_lo ^ (e_lo & (f_lo ^ g_lo))) >>> 0;
470
471 // Sum0(a) = ROTR 28(a) ^ ROTR 34(a) ^ ROTR 39(a)
472 s0_hi = (
473 ((a_hi >>> 28) | (a_lo << 4)) ^ // ROTR 28
474 ((a_lo >>> 2) | (a_hi << 30)) ^ // ROTR 34/(swap + ROTR 2)
475 ((a_lo >>> 7) | (a_hi << 25))) >>> 0; // ROTR 39/(swap + ROTR 7)
476 s0_lo = (
477 ((a_hi << 4) | (a_lo >>> 28)) ^ // ROTR 28
478 ((a_lo << 30) | (a_hi >>> 2)) ^ // ROTR 34/(swap + ROTR 2)
479 ((a_lo << 25) | (a_hi >>> 7))) >>> 0; // ROTR 39/(swap + ROTR 7)
480
481 // Maj(a, b, c) (optimized the same way as SHA-1)
482 maj_hi = ((a_hi & b_hi) | (c_hi & (a_hi ^ b_hi))) >>> 0;
483 maj_lo = ((a_lo & b_lo) | (c_lo & (a_lo ^ b_lo))) >>> 0;
484
485 // main algorithm
486 // t1 = (h + s1 + ch + _k[i] + _w[i]) modulo 2^64 (carry lo overflow)
487 lo = (h_lo + s1_lo + ch_lo + _k[i][1] + w[i][1]);
488 t1_hi = (h_hi + s1_hi + ch_hi + _k[i][0] + w[i][0] +
489 ((lo / 0x100000000) >>> 0)) >>> 0;
490 t1_lo = lo >>> 0;
491
492 // t2 = s0 + maj modulo 2^64 (carry lo overflow)
493 lo = s0_lo + maj_lo;
494 t2_hi = (s0_hi + maj_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
495 t2_lo = lo >>> 0;
496
497 h_hi = g_hi;
498 h_lo = g_lo;
499
500 g_hi = f_hi;
501 g_lo = f_lo;
502
503 f_hi = e_hi;
504 f_lo = e_lo;
505
506 // e = (d + t1) modulo 2^64 (carry lo overflow)
507 lo = d_lo + t1_lo;
508 e_hi = (d_hi + t1_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
509 e_lo = lo >>> 0;
510
511 d_hi = c_hi;
512 d_lo = c_lo;
513
514 c_hi = b_hi;
515 c_lo = b_lo;
516
517 b_hi = a_hi;
518 b_lo = a_lo;
519
520 // a = (t1 + t2) modulo 2^64 (carry lo overflow)
521 lo = t1_lo + t2_lo;
522 a_hi = (t1_hi + t2_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
523 a_lo = lo >>> 0;
524 }
525
526 // update hash state (additional modulo 2^64)
527 lo = s[0][1] + a_lo;
528 s[0][0] = (s[0][0] + a_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
529 s[0][1] = lo >>> 0;
530
531 lo = s[1][1] + b_lo;
532 s[1][0] = (s[1][0] + b_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
533 s[1][1] = lo >>> 0;
534
535 lo = s[2][1] + c_lo;
536 s[2][0] = (s[2][0] + c_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
537 s[2][1] = lo >>> 0;
538
539 lo = s[3][1] + d_lo;
540 s[3][0] = (s[3][0] + d_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
541 s[3][1] = lo >>> 0;
542
543 lo = s[4][1] + e_lo;
544 s[4][0] = (s[4][0] + e_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
545 s[4][1] = lo >>> 0;
546
547 lo = s[5][1] + f_lo;
548 s[5][0] = (s[5][0] + f_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
549 s[5][1] = lo >>> 0;
550
551 lo = s[6][1] + g_lo;
552 s[6][0] = (s[6][0] + g_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
553 s[6][1] = lo >>> 0;
554
555 lo = s[7][1] + h_lo;
556 s[7][0] = (s[7][0] + h_hi + ((lo / 0x100000000) >>> 0)) >>> 0;
557 s[7][1] = lo >>> 0;
558
559 len -= 128;
560 }
561}
Note: See TracBrowser for help on using the repository browser.