source: trip-planner-front/node_modules/node-forge/lib/sha256.js

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

initial commit

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/**
2 * Secure Hash Algorithm with 256-bit digest (SHA-256) implementation.
3 *
4 * See FIPS 180-2 for details.
5 *
6 * @author Dave Longley
7 *
8 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
9 */
10var forge = require('./forge');
11require('./md');
12require('./util');
13
14var sha256 = module.exports = forge.sha256 = forge.sha256 || {};
15forge.md.sha256 = forge.md.algorithms.sha256 = sha256;
16
17/**
18 * Creates a SHA-256 message digest object.
19 *
20 * @return a message digest object.
21 */
22sha256.create = function() {
23 // do initialization as necessary
24 if(!_initialized) {
25 _init();
26 }
27
28 // SHA-256 state contains eight 32-bit integers
29 var _state = null;
30
31 // input buffer
32 var _input = forge.util.createBuffer();
33
34 // used for word storage
35 var _w = new Array(64);
36
37 // message digest object
38 var md = {
39 algorithm: 'sha256',
40 blockLength: 64,
41 digestLength: 32,
42 // 56-bit length of message so far (does not including padding)
43 messageLength: 0,
44 // true message length
45 fullMessageLength: null,
46 // size of message length in bytes
47 messageLengthSize: 8
48 };
49
50 /**
51 * Starts the digest.
52 *
53 * @return this digest object.
54 */
55 md.start = function() {
56 // up to 56-bit message length for convenience
57 md.messageLength = 0;
58
59 // full message length (set md.messageLength64 for backwards-compatibility)
60 md.fullMessageLength = md.messageLength64 = [];
61 var int32s = md.messageLengthSize / 4;
62 for(var i = 0; i < int32s; ++i) {
63 md.fullMessageLength.push(0);
64 }
65 _input = forge.util.createBuffer();
66 _state = {
67 h0: 0x6A09E667,
68 h1: 0xBB67AE85,
69 h2: 0x3C6EF372,
70 h3: 0xA54FF53A,
71 h4: 0x510E527F,
72 h5: 0x9B05688C,
73 h6: 0x1F83D9AB,
74 h7: 0x5BE0CD19
75 };
76 return md;
77 };
78 // start digest automatically for first time
79 md.start();
80
81 /**
82 * Updates the digest with the given message input. The given input can
83 * treated as raw input (no encoding will be applied) or an encoding of
84 * 'utf8' maybe given to encode the input using UTF-8.
85 *
86 * @param msg the message input to update with.
87 * @param encoding the encoding to use (default: 'raw', other: 'utf8').
88 *
89 * @return this digest object.
90 */
91 md.update = function(msg, encoding) {
92 if(encoding === 'utf8') {
93 msg = forge.util.encodeUtf8(msg);
94 }
95
96 // update message length
97 var len = msg.length;
98 md.messageLength += len;
99 len = [(len / 0x100000000) >>> 0, len >>> 0];
100 for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
101 md.fullMessageLength[i] += len[1];
102 len[1] = len[0] + ((md.fullMessageLength[i] / 0x100000000) >>> 0);
103 md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
104 len[0] = ((len[1] / 0x100000000) >>> 0);
105 }
106
107 // add bytes to input buffer
108 _input.putBytes(msg);
109
110 // process bytes
111 _update(_state, _w, _input);
112
113 // compact input buffer every 2K or if empty
114 if(_input.read > 2048 || _input.length() === 0) {
115 _input.compact();
116 }
117
118 return md;
119 };
120
121 /**
122 * Produces the digest.
123 *
124 * @return a byte buffer containing the digest value.
125 */
126 md.digest = function() {
127 /* Note: Here we copy the remaining bytes in the input buffer and
128 add the appropriate SHA-256 padding. Then we do the final update
129 on a copy of the state so that if the user wants to get
130 intermediate digests they can do so. */
131
132 /* Determine the number of bytes that must be added to the message
133 to ensure its length is congruent to 448 mod 512. In other words,
134 the data to be digested must be a multiple of 512 bits (or 128 bytes).
135 This data includes the message, some padding, and the length of the
136 message. Since the length of the message will be encoded as 8 bytes (64
137 bits), that means that the last segment of the data must have 56 bytes
138 (448 bits) of message and padding. Therefore, the length of the message
139 plus the padding must be congruent to 448 mod 512 because
140 512 - 128 = 448.
141
142 In order to fill up the message length it must be filled with
143 padding that begins with 1 bit followed by all 0 bits. Padding
144 must *always* be present, so if the message length is already
145 congruent to 448 mod 512, then 512 padding bits must be added. */
146
147 var finalBlock = forge.util.createBuffer();
148 finalBlock.putBytes(_input.bytes());
149
150 // compute remaining size to be digested (include message length size)
151 var remaining = (
152 md.fullMessageLength[md.fullMessageLength.length - 1] +
153 md.messageLengthSize);
154
155 // add padding for overflow blockSize - overflow
156 // _padding starts with 1 byte with first bit is set (byte value 128), then
157 // there may be up to (blockSize - 1) other pad bytes
158 var overflow = remaining & (md.blockLength - 1);
159 finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
160
161 // serialize message length in bits in big-endian order; since length
162 // is stored in bytes we multiply by 8 and add carry from next int
163 var next, carry;
164 var bits = md.fullMessageLength[0] * 8;
165 for(var i = 0; i < md.fullMessageLength.length - 1; ++i) {
166 next = md.fullMessageLength[i + 1] * 8;
167 carry = (next / 0x100000000) >>> 0;
168 bits += carry;
169 finalBlock.putInt32(bits >>> 0);
170 bits = next >>> 0;
171 }
172 finalBlock.putInt32(bits);
173
174 var s2 = {
175 h0: _state.h0,
176 h1: _state.h1,
177 h2: _state.h2,
178 h3: _state.h3,
179 h4: _state.h4,
180 h5: _state.h5,
181 h6: _state.h6,
182 h7: _state.h7
183 };
184 _update(s2, _w, finalBlock);
185 var rval = forge.util.createBuffer();
186 rval.putInt32(s2.h0);
187 rval.putInt32(s2.h1);
188 rval.putInt32(s2.h2);
189 rval.putInt32(s2.h3);
190 rval.putInt32(s2.h4);
191 rval.putInt32(s2.h5);
192 rval.putInt32(s2.h6);
193 rval.putInt32(s2.h7);
194 return rval;
195 };
196
197 return md;
198};
199
200// sha-256 padding bytes not initialized yet
201var _padding = null;
202var _initialized = false;
203
204// table of constants
205var _k = null;
206
207/**
208 * Initializes the constant tables.
209 */
210function _init() {
211 // create padding
212 _padding = String.fromCharCode(128);
213 _padding += forge.util.fillString(String.fromCharCode(0x00), 64);
214
215 // create K table for SHA-256
216 _k = [
217 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
218 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
219 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
220 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
221 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
222 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
223 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
224 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
225 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
226 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
227 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
228 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
229 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
230 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
231 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
232 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
233
234 // now initialized
235 _initialized = true;
236}
237
238/**
239 * Updates a SHA-256 state with the given byte buffer.
240 *
241 * @param s the SHA-256 state to update.
242 * @param w the array to use to store words.
243 * @param bytes the byte buffer to update with.
244 */
245function _update(s, w, bytes) {
246 // consume 512 bit (64 byte) chunks
247 var t1, t2, s0, s1, ch, maj, i, a, b, c, d, e, f, g, h;
248 var len = bytes.length();
249 while(len >= 64) {
250 // the w array will be populated with sixteen 32-bit big-endian words
251 // and then extended into 64 32-bit words according to SHA-256
252 for(i = 0; i < 16; ++i) {
253 w[i] = bytes.getInt32();
254 }
255 for(; i < 64; ++i) {
256 // XOR word 2 words ago rot right 17, rot right 19, shft right 10
257 t1 = w[i - 2];
258 t1 =
259 ((t1 >>> 17) | (t1 << 15)) ^
260 ((t1 >>> 19) | (t1 << 13)) ^
261 (t1 >>> 10);
262 // XOR word 15 words ago rot right 7, rot right 18, shft right 3
263 t2 = w[i - 15];
264 t2 =
265 ((t2 >>> 7) | (t2 << 25)) ^
266 ((t2 >>> 18) | (t2 << 14)) ^
267 (t2 >>> 3);
268 // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^32
269 w[i] = (t1 + w[i - 7] + t2 + w[i - 16]) | 0;
270 }
271
272 // initialize hash value for this chunk
273 a = s.h0;
274 b = s.h1;
275 c = s.h2;
276 d = s.h3;
277 e = s.h4;
278 f = s.h5;
279 g = s.h6;
280 h = s.h7;
281
282 // round function
283 for(i = 0; i < 64; ++i) {
284 // Sum1(e)
285 s1 =
286 ((e >>> 6) | (e << 26)) ^
287 ((e >>> 11) | (e << 21)) ^
288 ((e >>> 25) | (e << 7));
289 // Ch(e, f, g) (optimized the same way as SHA-1)
290 ch = g ^ (e & (f ^ g));
291 // Sum0(a)
292 s0 =
293 ((a >>> 2) | (a << 30)) ^
294 ((a >>> 13) | (a << 19)) ^
295 ((a >>> 22) | (a << 10));
296 // Maj(a, b, c) (optimized the same way as SHA-1)
297 maj = (a & b) | (c & (a ^ b));
298
299 // main algorithm
300 t1 = h + s1 + ch + _k[i] + w[i];
301 t2 = s0 + maj;
302 h = g;
303 g = f;
304 f = e;
305 // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
306 // can't truncate with `| 0`
307 e = (d + t1) >>> 0;
308 d = c;
309 c = b;
310 b = a;
311 // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
312 // can't truncate with `| 0`
313 a = (t1 + t2) >>> 0;
314 }
315
316 // update hash state
317 s.h0 = (s.h0 + a) | 0;
318 s.h1 = (s.h1 + b) | 0;
319 s.h2 = (s.h2 + c) | 0;
320 s.h3 = (s.h3 + d) | 0;
321 s.h4 = (s.h4 + e) | 0;
322 s.h5 = (s.h5 + f) | 0;
323 s.h6 = (s.h6 + g) | 0;
324 s.h7 = (s.h7 + h) | 0;
325 len -= 64;
326 }
327}
Note: See TracBrowser for help on using the repository browser.