| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * SHA-1. | 6 * SHA-1. |
| 7 * Ripped from package:crypto. | 7 * Ripped from package:crypto. |
| 8 */ | 8 */ |
| 9 library sha1; | 9 library sha1; |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 * | 47 * |
| 48 * If [addLineSeparator] is true, the resulting string will be | 48 * If [addLineSeparator] is true, the resulting string will be |
| 49 * broken into lines of 76 characters, separated by "\r\n". | 49 * broken into lines of 76 characters, separated by "\r\n". |
| 50 * | 50 * |
| 51 * If [urlSafe] is true, the result is URL and filename safe. | 51 * If [urlSafe] is true, the result is URL and filename safe. |
| 52 * | 52 * |
| 53 * Based on [RFC 4648](http://tools.ietf.org/html/rfc4648) | 53 * Based on [RFC 4648](http://tools.ietf.org/html/rfc4648) |
| 54 * | 54 * |
| 55 */ | 55 */ |
| 56 String _bytesToBase64(List<int> bytes, | 56 String _bytesToBase64(List<int> bytes, |
| 57 {bool urlSafe : false, | 57 {bool urlSafe: false, bool addLineSeparator: false}) { |
| 58 bool addLineSeparator : false}) { | 58 return _CryptoUtils.bytesToBase64(bytes, urlSafe, addLineSeparator); |
| 59 return _CryptoUtils.bytesToBase64(bytes, | |
| 60 urlSafe, | |
| 61 addLineSeparator); | |
| 62 } | 59 } |
| 63 } | 60 } |
| 64 | 61 |
| 65 | |
| 66 // Constants. | 62 // Constants. |
| 67 const _MASK_8 = 0xff; | 63 const _MASK_8 = 0xff; |
| 68 const _MASK_32 = 0xffffffff; | 64 const _MASK_32 = 0xffffffff; |
| 69 const _BITS_PER_BYTE = 8; | 65 const _BITS_PER_BYTE = 8; |
| 70 const _BYTES_PER_WORD = 4; | 66 const _BYTES_PER_WORD = 4; |
| 71 | 67 |
| 72 // Helper functions used by more than one hasher. | 68 // Helper functions used by more than one hasher. |
| 73 | 69 |
| 74 // Rotate left limiting to unsigned 32-bit values. | 70 // Rotate left limiting to unsigned 32-bit values. |
| 75 int _rotl32(int val, int shift) { | 71 int _rotl32(int val, int shift) { |
| 76 var mod_shift = shift & 31; | 72 var mod_shift = shift & 31; |
| 77 return ((val << mod_shift) & _MASK_32) | | 73 return ((val << mod_shift) & _MASK_32) | |
| 78 ((val & _MASK_32) >> (32 - mod_shift)); | 74 ((val & _MASK_32) >> (32 - mod_shift)); |
| 79 } | 75 } |
| 80 | 76 |
| 81 // Base class encapsulating common behavior for cryptographic hash | 77 // Base class encapsulating common behavior for cryptographic hash |
| 82 // functions. | 78 // functions. |
| 83 abstract class _HashBase implements Hash { | 79 abstract class _HashBase implements Hash { |
| 84 final int _chunkSizeInWords; | 80 final int _chunkSizeInWords; |
| 85 final int _digestSizeInWords; | 81 final int _digestSizeInWords; |
| 86 final bool _bigEndianWords; | 82 final bool _bigEndianWords; |
| 87 final List<int> _currentChunk; | 83 final List<int> _currentChunk; |
| 88 final List<int> _h; | 84 final List<int> _h; |
| 89 int _lengthInBytes = 0; | 85 int _lengthInBytes = 0; |
| 90 List<int> _pendingData; | 86 List<int> _pendingData; |
| 91 bool _digestCalled = false; | 87 bool _digestCalled = false; |
| 92 | 88 |
| 93 _HashBase(int chunkSizeInWords, | 89 _HashBase( |
| 94 int digestSizeInWords, | 90 int chunkSizeInWords, int digestSizeInWords, bool this._bigEndianWords) |
| 95 bool this._bigEndianWords) | |
| 96 : _pendingData = [], | 91 : _pendingData = [], |
| 97 _currentChunk = new List(chunkSizeInWords), | 92 _currentChunk = new List(chunkSizeInWords), |
| 98 _h = new List(digestSizeInWords), | 93 _h = new List(digestSizeInWords), |
| 99 _chunkSizeInWords = chunkSizeInWords, | 94 _chunkSizeInWords = chunkSizeInWords, |
| 100 _digestSizeInWords = digestSizeInWords; | 95 _digestSizeInWords = digestSizeInWords; |
| 101 | 96 |
| 102 // Update the hasher with more data. | 97 // Update the hasher with more data. |
| 103 void add(List<int> data) { | 98 void add(List<int> data) { |
| 104 if (_digestCalled) { | 99 if (_digestCalled) { |
| 105 throw new StateError( | 100 throw new StateError( |
| 106 'Hash update method called after digest was retrieved'); | 101 'Hash update method called after digest was retrieved'); |
| 107 } | 102 } |
| 108 _lengthInBytes += data.length; | 103 _lengthInBytes += data.length; |
| 109 _pendingData.addAll(data); | 104 _pendingData.addAll(data); |
| 110 _iterate(); | 105 _iterate(); |
| 111 } | 106 } |
| 112 | 107 |
| 113 // Finish the hash computation and return the digest string. | 108 // Finish the hash computation and return the digest string. |
| 114 List<int> close() { | 109 List<int> close() { |
| 115 if (_digestCalled) { | 110 if (_digestCalled) { |
| 116 return _resultAsBytes(); | 111 return _resultAsBytes(); |
| 117 } | 112 } |
| 118 _digestCalled = true; | 113 _digestCalled = true; |
| 119 _finalizeData(); | 114 _finalizeData(); |
| 120 _iterate(); | 115 _iterate(); |
| 121 assert(_pendingData.length == 0); | 116 assert(_pendingData.length == 0); |
| 122 return _resultAsBytes(); | 117 return _resultAsBytes(); |
| 123 } | 118 } |
| 124 | 119 |
| 125 // Returns the block size of the hash in bytes. | 120 // Returns the block size of the hash in bytes. |
| 126 int get blockSize { | 121 int get blockSize { |
| 127 return _chunkSizeInWords * _BYTES_PER_WORD; | 122 return _chunkSizeInWords * _BYTES_PER_WORD; |
| 128 } | 123 } |
| 129 | 124 |
| 130 // One round of the hash computation. | 125 // One round of the hash computation. |
| 131 void _updateHash(List<int> m); | 126 void _updateHash(List<int> m); |
| 132 | 127 |
| 133 // Helper methods. | 128 // Helper methods. |
| 134 int _add32(x, y) => (x + y) & _MASK_32; | 129 int _add32(x, y) => (x + y) & _MASK_32; |
| 135 int _roundUp(val, n) => (val + n - 1) & -n; | 130 int _roundUp(val, n) => (val + n - 1) & -n; |
| 136 | 131 |
| 137 // Compute the final result as a list of bytes from the hash words. | 132 // Compute the final result as a list of bytes from the hash words. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 if (_bigEndianWords) { | 197 if (_bigEndianWords) { |
| 203 _pendingData.addAll(_wordToBytes(0)); | 198 _pendingData.addAll(_wordToBytes(0)); |
| 204 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); | 199 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); |
| 205 } else { | 200 } else { |
| 206 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); | 201 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); |
| 207 _pendingData.addAll(_wordToBytes(0)); | 202 _pendingData.addAll(_wordToBytes(0)); |
| 208 } | 203 } |
| 209 } | 204 } |
| 210 } | 205 } |
| 211 | 206 |
| 212 | |
| 213 /** | 207 /** |
| 214 * Interface for cryptographic hash functions. | 208 * Interface for cryptographic hash functions. |
| 215 * | 209 * |
| 216 * The [add] method is used to add data to the hash. The [close] method | 210 * The [add] method is used to add data to the hash. The [close] method |
| 217 * is used to extract the message digest. | 211 * is used to extract the message digest. |
| 218 * | 212 * |
| 219 * Once the [close] method has been called no more data can be added using the | 213 * Once the [close] method has been called no more data can be added using the |
| 220 * [add] method. If [add] is called after the first call to [close] a | 214 * [add] method. If [add] is called after the first call to [close] a |
| 221 * HashException is thrown. | 215 * HashException is thrown. |
| 222 * | 216 * |
| (...skipping 22 matching lines...) Expand all Loading... |
| 245 int get blockSize; | 239 int get blockSize; |
| 246 } | 240 } |
| 247 | 241 |
| 248 /** | 242 /** |
| 249 * SHA1 hash function implementation. | 243 * SHA1 hash function implementation. |
| 250 */ | 244 */ |
| 251 class SHA1 extends _HashBase { | 245 class SHA1 extends _HashBase { |
| 252 final List<int> _w; | 246 final List<int> _w; |
| 253 | 247 |
| 254 // Construct a SHA1 hasher object. | 248 // Construct a SHA1 hasher object. |
| 255 SHA1() : _w = new List(80), super(16, 5, true) { | 249 SHA1() |
| 250 : _w = new List(80), |
| 251 super(16, 5, true) { |
| 256 _h[0] = 0x67452301; | 252 _h[0] = 0x67452301; |
| 257 _h[1] = 0xEFCDAB89; | 253 _h[1] = 0xEFCDAB89; |
| 258 _h[2] = 0x98BADCFE; | 254 _h[2] = 0x98BADCFE; |
| 259 _h[3] = 0x10325476; | 255 _h[3] = 0x10325476; |
| 260 _h[4] = 0xC3D2E1F0; | 256 _h[4] = 0xC3D2E1F0; |
| 261 } | 257 } |
| 262 | 258 |
| 263 // Compute one iteration of the SHA1 algorithm with a chunk of | 259 // Compute one iteration of the SHA1 algorithm with a chunk of |
| 264 // 16 32-bit pieces. | 260 // 16 32-bit pieces. |
| 265 void _updateHash(List<int> m) { | 261 void _updateHash(List<int> m) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 294 |
| 299 _h[0] = _add32(a, _h[0]); | 295 _h[0] = _add32(a, _h[0]); |
| 300 _h[1] = _add32(b, _h[1]); | 296 _h[1] = _add32(b, _h[1]); |
| 301 _h[2] = _add32(c, _h[2]); | 297 _h[2] = _add32(c, _h[2]); |
| 302 _h[3] = _add32(d, _h[3]); | 298 _h[3] = _add32(d, _h[3]); |
| 303 _h[4] = _add32(e, _h[4]); | 299 _h[4] = _add32(e, _h[4]); |
| 304 } | 300 } |
| 305 } | 301 } |
| 306 | 302 |
| 307 abstract class _CryptoUtils { | 303 abstract class _CryptoUtils { |
| 308 | |
| 309 static const int PAD = 61; // '=' | 304 static const int PAD = 61; // '=' |
| 310 static const int CR = 13; // '\r' | 305 static const int CR = 13; // '\r' |
| 311 static const int LF = 10; // '\n' | 306 static const int LF = 10; // '\n' |
| 312 static const int LINE_LENGTH = 76; | 307 static const int LINE_LENGTH = 76; |
| 313 | 308 |
| 314 static const String _encodeTable = | 309 static const String _encodeTable = |
| 315 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 310 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 316 | 311 |
| 317 static const String _encodeTableUrlSafe = | 312 static const String _encodeTableUrlSafe = |
| 318 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; | 313 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; |
| 319 | 314 |
| 320 static String bytesToBase64(List<int> bytes, | 315 static String bytesToBase64(List<int> bytes, |
| 321 [bool urlSafe = false, | 316 [bool urlSafe = false, bool addLineSeparator = false]) { |
| 322 bool addLineSeparator = false]) { | |
| 323 int len = bytes.length; | 317 int len = bytes.length; |
| 324 if (len == 0) { | 318 if (len == 0) { |
| 325 return ""; | 319 return ""; |
| 326 } | 320 } |
| 327 final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable; | 321 final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable; |
| 328 // Size of 24 bit chunks. | 322 // Size of 24 bit chunks. |
| 329 final int remainderLength = len.remainder(3); | 323 final int remainderLength = len.remainder(3); |
| 330 final int chunkLength = len - remainderLength; | 324 final int chunkLength = len - remainderLength; |
| 331 // Size of base output. | 325 // Size of base output. |
| 332 int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0); | 326 int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0); |
| 333 // Add extra for line separators. | 327 // Add extra for line separators. |
| 334 if (addLineSeparator) { | 328 if (addLineSeparator) { |
| 335 outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1; | 329 outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1; |
| 336 } | 330 } |
| 337 List<int> out = new List<int>(outputLen); | 331 List<int> out = new List<int>(outputLen); |
| 338 | 332 |
| 339 // Encode 24 bit chunks. | 333 // Encode 24 bit chunks. |
| 340 int j = 0, i = 0, c = 0; | 334 int j = 0, i = 0, c = 0; |
| 341 while (i < chunkLength) { | 335 while (i < chunkLength) { |
| 342 int x = ((bytes[i++] << 16) & 0xFFFFFF) | | 336 int x = ((bytes[i++] << 16) & 0xFFFFFF) | |
| 343 ((bytes[i++] << 8) & 0xFFFFFF) | | 337 ((bytes[i++] << 8) & 0xFFFFFF) | |
| 344 bytes[i++]; | 338 bytes[i++]; |
| 345 out[j++] = lookup.codeUnitAt(x >> 18); | 339 out[j++] = lookup.codeUnitAt(x >> 18); |
| 346 out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F); | 340 out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F); |
| 347 out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F); | 341 out[j++] = lookup.codeUnitAt((x >> 6) & 0x3F); |
| 348 out[j++] = lookup.codeUnitAt(x & 0x3f); | 342 out[j++] = lookup.codeUnitAt(x & 0x3f); |
| 349 // Add optional line separator for each 76 char output. | 343 // Add optional line separator for each 76 char output. |
| 350 if (addLineSeparator && ++c == 19 && j < outputLen - 2) { | 344 if (addLineSeparator && ++c == 19 && j < outputLen - 2) { |
| 351 out[j++] = CR; | 345 out[j++] = CR; |
| 352 out[j++] = LF; | 346 out[j++] = LF; |
| 353 c = 0; | 347 c = 0; |
| 354 } | 348 } |
| 355 } | 349 } |
| 356 | 350 |
| 357 // If input length if not a multiple of 3, encode remaining bytes and | 351 // If input length if not a multiple of 3, encode remaining bytes and |
| 358 // add padding. | 352 // add padding. |
| 359 if (remainderLength == 1) { | 353 if (remainderLength == 1) { |
| 360 int x = bytes[i]; | 354 int x = bytes[i]; |
| 361 out[j++] = lookup.codeUnitAt(x >> 2); | 355 out[j++] = lookup.codeUnitAt(x >> 2); |
| 362 out[j++] = lookup.codeUnitAt((x << 4) & 0x3F); | 356 out[j++] = lookup.codeUnitAt((x << 4) & 0x3F); |
| 363 out[j++] = PAD; | 357 out[j++] = PAD; |
| 364 out[j++] = PAD; | 358 out[j++] = PAD; |
| 365 } else if (remainderLength == 2) { | 359 } else if (remainderLength == 2) { |
| 366 int x = bytes[i]; | 360 int x = bytes[i]; |
| 367 int y = bytes[i + 1]; | 361 int y = bytes[i + 1]; |
| 368 out[j++] = lookup.codeUnitAt(x >> 2); | 362 out[j++] = lookup.codeUnitAt(x >> 2); |
| 369 out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F); | 363 out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F); |
| 370 out[j++] = lookup.codeUnitAt((y << 2) & 0x3F); | 364 out[j++] = lookup.codeUnitAt((y << 2) & 0x3F); |
| 371 out[j++] = PAD; | 365 out[j++] = PAD; |
| 372 } | 366 } |
| 373 | 367 |
| 374 return new String.fromCharCodes(out); | 368 return new String.fromCharCodes(out); |
| 375 } | 369 } |
| 376 } | 370 } |
| OLD | NEW |