Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/io/crypto.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart.io;
6
7 class _CryptoUtils {
8 static const int PAD = 61; // '='
9 static const int CR = 13; // '\r'
10 static const int LF = 10; // '\n'
11 static const int LINE_LENGTH = 76;
12
13 static const String _encodeTable =
14 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
15
16 static const String _encodeTableUrlSafe =
17 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
18
19 // Lookup table used for finding Base 64 alphabet index of a given byte.
20 // -2 : Outside Base 64 alphabet.
21 // -1 : '\r' or '\n'
22 // 0 : = (Padding character).
23 // >0 : Base 64 alphabet index of given byte.
24 static const List<int> _decodeTable =
25 const [ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2,
26 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
27 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63,
28 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, 0, -2, -2,
29 -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
30 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63,
31 -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
32 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
33 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
34 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
35 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
36 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
37 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
38 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
39 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
40 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 ];
41
42 static String bytesToHex(List<int> bytes) {
43 var result = new StringBuffer();
44 for (var part in bytes) {
45 result.write('${part < 16 ? '0' : ''}${part.toRadixString(16)}');
46 }
47 return result.toString();
48 }
49
50 static String bytesToBase64(List<int> bytes,
51 [bool urlSafe = false,
52 bool addLineSeparator = false]) {
53 int len = bytes.length;
54 if (len == 0) {
55 return "";
56 }
57 final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable;
58 // Size of 24 bit chunks.
59 final int remainderLength = len.remainder(3);
60 final int chunkLength = len - remainderLength;
61 // Size of base output.
62 int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0);
63 // Add extra for line separators.
64 if (addLineSeparator) {
65 outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1;
66 }
67 List<int> out = new List<int>(outputLen);
68
69 // Encode 24 bit chunks.
70 int j = 0, i = 0, c = 0;
71 while (i < chunkLength) {
72 int x = ((bytes[i++] << 16) & 0xFFFFFF) |
73 ((bytes[i++] << 8) & 0xFFFFFF) |
74 bytes[i++];
75 out[j++] = lookup.codeUnitAt(x >> 18);
76 out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F);
77 out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F);
78 out[j++] = lookup.codeUnitAt(x & 0x3f);
79 // Add optional line separator for each 76 char output.
80 if (addLineSeparator && ++c == 19 && j < outputLen - 2) {
81 out[j++] = CR;
82 out[j++] = LF;
83 c = 0;
84 }
85 }
86
87 // If input length if not a multiple of 3, encode remaining bytes and
88 // add padding.
89 if (remainderLength == 1) {
90 int x = bytes[i];
91 out[j++] = lookup.codeUnitAt(x >> 2);
92 out[j++] = lookup.codeUnitAt((x << 4) & 0x3F);
93 out[j++] = PAD;
94 out[j++] = PAD;
95 } else if (remainderLength == 2) {
96 int x = bytes[i];
97 int y = bytes[i + 1];
98 out[j++] = lookup.codeUnitAt(x >> 2);
99 out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F);
100 out[j++] = lookup.codeUnitAt((y << 2) & 0x3F);
101 out[j++] = PAD;
102 }
103
104 return new String.fromCharCodes(out);
105 }
106
107 static List<int> base64StringToBytes(String input,
108 [bool ignoreInvalidCharacters = true]) {
109 int len = input.length;
110 if (len == 0) {
111 return new List<int>(0);
112 }
113
114 // Count '\r', '\n' and illegal characters, For illegal characters,
115 // if [ignoreInvalidCharacters] is false, throw an exception.
116 int extrasLen = 0;
117 for (int i = 0; i < len; i++) {
118 int c = _decodeTable[input.codeUnitAt(i)];
119 if (c < 0) {
120 extrasLen++;
121 if(c == -2 && !ignoreInvalidCharacters) {
122 throw new FormatException('Invalid character: ${input[i]}');
123 }
124 }
125 }
126
127 if ((len - extrasLen) % 4 != 0) {
128 throw new FormatException('''Size of Base 64 characters in Input
129 must be a multiple of 4. Input: $input''');
130 }
131
132 // Count pad characters, ignore illegal characters at the end.
133 int padLength = 0;
134 for (int i = len - 1; i >= 0; i--) {
135 int currentCodeUnit = input.codeUnitAt(i);
136 if (_decodeTable[currentCodeUnit] > 0) break;
137 if (currentCodeUnit == PAD) padLength++;
138 }
139 int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
140 List<int> out = new List<int>(outputLen);
141
142 for (int i = 0, o = 0; o < outputLen;) {
143 // Accumulate 4 valid 6 bit Base 64 characters into an int.
144 int x = 0;
145 for (int j = 4; j > 0;) {
146 int c = _decodeTable[input.codeUnitAt(i++)];
147 if (c >= 0) {
148 x = ((x << 6) & 0xFFFFFF) | c;
149 j--;
150 }
151 }
152 out[o++] = x >> 16;
153 if (o < outputLen) {
154 out[o++] = (x >> 8) & 0xFF;
155 if (o < outputLen) out[o++] = x & 0xFF;
156 }
157 }
158 return out;
159 }
160
161 }
162
163 // Constants.
164 const _MASK_8 = 0xff;
165 const _MASK_32 = 0xffffffff;
166 const _BITS_PER_BYTE = 8;
167 const _BYTES_PER_WORD = 4;
168
169 // Base class encapsulating common behavior for cryptographic hash
170 // functions.
171 abstract class _HashBase {
172 // Hasher state.
173 final int _chunkSizeInWords;
174 final int _digestSizeInWords;
175 final bool _bigEndianWords;
176 int _lengthInBytes = 0;
177 List<int> _pendingData;
178 List<int> _currentChunk;
179 List<int> _h;
180 bool _digestCalled = false;
181
182 _HashBase(this._chunkSizeInWords,
183 this._digestSizeInWords,
184 this._bigEndianWords)
185 : _pendingData = [] {
186 _currentChunk = new List(_chunkSizeInWords);
187 _h = new List(_digestSizeInWords);
188 }
189
190 // Update the hasher with more data.
191 add(List<int> data) {
192 if (_digestCalled) {
193 throw new StateError(
194 'Hash update method called after digest was retrieved');
195 }
196 _lengthInBytes += data.length;
197 _pendingData.addAll(data);
198 _iterate();
199 }
200
201 // Finish the hash computation and return the digest string.
202 List<int> close() {
203 if (_digestCalled) {
204 return _resultAsBytes();
205 }
206 _digestCalled = true;
207 _finalizeData();
208 _iterate();
209 assert(_pendingData.length == 0);
210 return _resultAsBytes();
211 }
212
213 // Returns the block size of the hash in bytes.
214 int get blockSize {
215 return _chunkSizeInWords * _BYTES_PER_WORD;
216 }
217
218 // Create a fresh instance of this Hash.
219 newInstance();
220
221 // One round of the hash computation.
222 _updateHash(List<int> m);
223
224 // Helper methods.
225 _add32(x, y) => (x + y) & _MASK_32;
226 _roundUp(val, n) => (val + n - 1) & -n;
227
228 // Rotate left limiting to unsigned 32-bit values.
229 int _rotl32(int val, int shift) {
230 var mod_shift = shift & 31;
231 return ((val << mod_shift) & _MASK_32) |
232 ((val & _MASK_32) >> (32 - mod_shift));
233 }
234
235
236 // Compute the final result as a list of bytes from the hash words.
237 _resultAsBytes() {
238 var result = [];
239 for (var i = 0; i < _h.length; i++) {
240 result.addAll(_wordToBytes(_h[i]));
241 }
242 return result;
243 }
244
245 // Converts a list of bytes to a chunk of 32-bit words.
246 _bytesToChunk(List<int> data, int dataIndex) {
247 assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
248
249 for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
250 var w3 = _bigEndianWords ? data[dataIndex] : data[dataIndex + 3];
251 var w2 = _bigEndianWords ? data[dataIndex + 1] : data[dataIndex + 2];
252 var w1 = _bigEndianWords ? data[dataIndex + 2] : data[dataIndex + 1];
253 var w0 = _bigEndianWords ? data[dataIndex + 3] : data[dataIndex];
254 dataIndex += 4;
255 var word = (w3 & 0xff) << 24;
256 word |= (w2 & _MASK_8) << 16;
257 word |= (w1 & _MASK_8) << 8;
258 word |= (w0 & _MASK_8);
259 _currentChunk[wordIndex] = word;
260 }
261 }
262
263 // Convert a 32-bit word to four bytes.
264 _wordToBytes(int word) {
265 List<int> bytes = new List(_BYTES_PER_WORD);
266 bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
267 bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
268 bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8;
269 bytes[3] = (word >> (_bigEndianWords ? 0 : 24)) & _MASK_8;
270 return bytes;
271 }
272
273 // Iterate through data updating the hash computation for each
274 // chunk.
275 _iterate() {
276 var len = _pendingData.length;
277 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
278 if (len >= chunkSizeInBytes) {
279 var index = 0;
280 for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) {
281 _bytesToChunk(_pendingData, index);
282 _updateHash(_currentChunk);
283 }
284 _pendingData = _pendingData.sublist(index, len);
285 }
286 }
287
288 // Finalize the data. Add a 1 bit to the end of the message. Expand with
289 // 0 bits and add the length of the message.
290 _finalizeData() {
291 _pendingData.add(0x80);
292 var contentsLength = _lengthInBytes + 9;
293 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
294 var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes);
295 var zeroPadding = finalizedLength - contentsLength;
296 for (var i = 0; i < zeroPadding; i++) {
297 _pendingData.add(0);
298 }
299 var lengthInBits = _lengthInBytes * _BITS_PER_BYTE;
300 assert(lengthInBits < pow(2, 32));
301 if (_bigEndianWords) {
302 _pendingData.addAll(_wordToBytes(0));
303 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
304 } else {
305 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
306 _pendingData.addAll(_wordToBytes(0));
307 }
308 }
309 }
310
311 // The MD5 hasher is used to compute an MD5 message digest.
312 class _MD5 extends _HashBase {
313 _MD5() : super(16, 4, false) {
314 _h[0] = 0x67452301;
315 _h[1] = 0xefcdab89;
316 _h[2] = 0x98badcfe;
317 _h[3] = 0x10325476;
318 }
319
320 // Returns a new instance of this Hash.
321 _MD5 newInstance() {
322 return new _MD5();
323 }
324
325 static const _k = const [
326 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
327 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
328 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
329 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
330 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
331 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
332 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa,
333 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
334 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92,
335 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
336 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 ];
337
338 static const _r = const [
339 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14,
340 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11,
341 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6,
342 10, 15, 21, 6, 10, 15, 21 ];
343
344 // Compute one iteration of the MD5 algorithm with a chunk of
345 // 16 32-bit pieces.
346 void _updateHash(List<int> m) {
347 assert(m.length == 16);
348
349 var a = _h[0];
350 var b = _h[1];
351 var c = _h[2];
352 var d = _h[3];
353
354 var t0;
355 var t1;
356
357 for (var i = 0; i < 64; i++) {
358 if (i < 16) {
359 t0 = (b & c) | ((~b & _MASK_32) & d);
360 t1 = i;
361 } else if (i < 32) {
362 t0 = (d & b) | ((~d & _MASK_32) & c);
363 t1 = ((5 * i) + 1) % 16;
364 } else if (i < 48) {
365 t0 = b ^ c ^ d;
366 t1 = ((3 * i) + 5) % 16;
367 } else {
368 t0 = c ^ (b | (~d & _MASK_32));
369 t1 = (7 * i) % 16;
370 }
371
372 var temp = d;
373 d = c;
374 c = b;
375 b = _add32(b, _rotl32(_add32(_add32(a, t0),
376 _add32(_k[i], m[t1])),
377 _r[i]));
378 a = temp;
379 }
380
381 _h[0] = _add32(a, _h[0]);
382 _h[1] = _add32(b, _h[1]);
383 _h[2] = _add32(c, _h[2]);
384 _h[3] = _add32(d, _h[3]);
385 }
386 }
387
388 // The SHA1 hasher is used to compute an SHA1 message digest.
389 class _SHA1 extends _HashBase {
390 // Construct a SHA1 hasher object.
391 _SHA1() : _w = new List(80), super(16, 5, true) {
392 _h[0] = 0x67452301;
393 _h[1] = 0xEFCDAB89;
394 _h[2] = 0x98BADCFE;
395 _h[3] = 0x10325476;
396 _h[4] = 0xC3D2E1F0;
397 }
398
399 // Returns a new instance of this Hash.
400 _SHA1 newInstance() {
401 return new _SHA1();
402 }
403
404 // Compute one iteration of the SHA1 algorithm with a chunk of
405 // 16 32-bit pieces.
406 void _updateHash(List<int> m) {
407 assert(m.length == 16);
408
409 var a = _h[0];
410 var b = _h[1];
411 var c = _h[2];
412 var d = _h[3];
413 var e = _h[4];
414
415 for (var i = 0; i < 80; i++) {
416 if (i < 16) {
417 _w[i] = m[i];
418 } else {
419 var n = _w[i - 3] ^ _w[i - 8] ^ _w[i - 14] ^ _w[i - 16];
420 _w[i] = _rotl32(n, 1);
421 }
422 var t = _add32(_add32(_rotl32(a, 5), e), _w[i]);
423 if (i < 20) {
424 t = _add32(_add32(t, (b & c) | (~b & d)), 0x5A827999);
425 } else if (i < 40) {
426 t = _add32(_add32(t, (b ^ c ^ d)), 0x6ED9EBA1);
427 } else if (i < 60) {
428 t = _add32(_add32(t, (b & c) | (b & d) | (c & d)), 0x8F1BBCDC);
429 } else {
430 t = _add32(_add32(t, b ^ c ^ d), 0xCA62C1D6);
431 }
432
433 e = d;
434 d = c;
435 c = _rotl32(b, 30);
436 b = a;
437 a = t & _MASK_32;
438 }
439
440 _h[0] = _add32(a, _h[0]);
441 _h[1] = _add32(b, _h[1]);
442 _h[2] = _add32(c, _h[2]);
443 _h[3] = _add32(d, _h[3]);
444 _h[4] = _add32(e, _h[4]);
445 }
446
447 List<int> _w;
448 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/io/common.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/io/data_transformer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698