source: trip-planner-front/node_modules/node-forge/lib/sha1.js@ 571e0df

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

initial commit

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