| 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 class SHA1 { | 5 // The SHA1 hasher is used to compute an SHA1 message digest. |
| 6 static List<int> digest(List<int> input, | 6 class _SHA1 extends _SHACryptoHashBase implements SHA1 { |
| 7 [int offset = 0, | 7 // Construct a SHA1 hasher object. |
| 8 int len = null]) { | 8 _SHA1() : _w = new List(80), super(16, 5) { |
| 9 var input_len = input.length; | 9 // Initial value of the hash parts. First 32 bits of the fractional parts |
| 10 if ((offset < 0) || (offset > input_len)) { | 10 // of the square roots of the first 8 prime numbers. |
| 11 throw new IllegalArgumentException("Invalid offset ($offset)."); | 11 _h[0] = 0x67452301; |
| 12 } | 12 _h[1] = 0xEFCDAB89; |
| 13 if (len == null) { | 13 _h[2] = 0x98BADCFE; |
| 14 len = input_len - offset; | 14 _h[3] = 0x10325476; |
| 15 } | 15 _h[4] = 0xC3D2E1F0; |
| 16 if ((len < 0) || ((offset + len) > input_len)) { | 16 } |
| 17 throw new IllegalArgumentException("Invalid length ($len) for " | 17 |
| 18 "offset ($offset) and input length (input_len)."); | 18 // Rotate left limiting to unsigned 32-bit values. |
| 19 int _rotl32(int val, int shift) { |
| 20 var mod_shift = shift & 31; |
| 21 return ((val << mod_shift) & _MASK_32) | |
| 22 ((val & _MASK_32) >> (32 - mod_shift)); |
| 23 } |
| 24 |
| 25 // Compute one iteration of the SHA1 algorithm with a chunk of |
| 26 // 16 32-bit pieces. |
| 27 void _updateHash(List<int> m) { |
| 28 assert(m.length == 16); |
| 29 |
| 30 var a = _h[0]; |
| 31 var b = _h[1]; |
| 32 var c = _h[2]; |
| 33 var d = _h[3]; |
| 34 var e = _h[4]; |
| 35 |
| 36 for (var i = 0; i < 80; i++) { |
| 37 if (i < 16) { |
| 38 _w[i] = m[i]; |
| 39 } else { |
| 40 var n = _w[i - 3] ^ _w[i - 8] ^ _w[i - 14] ^ _w[i - 16]; |
| 41 _w[i] = _rotl32(n, 1); |
| 42 } |
| 43 var t = _rotl32(a, 5) + e + _w[i]; |
| 44 if (i < 20) { |
| 45 t = t + ((b & c) | (~b & d)) + 0x5A827999; |
| 46 } else if (i < 40) { |
| 47 t = t + (b ^ c ^ d) + 0x6ED9EBA1; |
| 48 } else if (i < 60) { |
| 49 t = t + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC; |
| 50 } else { |
| 51 t = t + (b ^ c ^ d) + 0xCA62C1D6; |
| 52 } |
| 53 |
| 54 e = d; |
| 55 d = c; |
| 56 c = _rotl32(b, 30); |
| 57 b = a; |
| 58 a = t & _MASK_32; |
| 19 } | 59 } |
| 20 | 60 |
| 21 // Round up to 512 bit size. | 61 _h[0] = _add32(a, _h[0]); |
| 22 var m_len = _roundUp((len * _BITS_PER_BYTE) + 65, _BITS_PER_CHUNK); | 62 _h[1] = _add32(b, _h[1]); |
| 23 m_len = m_len ~/ _BITS_PER_WORD; | 63 _h[2] = _add32(c, _h[2]); |
| 24 var m = new List<int>(m_len); | 64 _h[3] = _add32(d, _h[3]); |
| 25 | 65 _h[4] = _add32(e, _h[4]); |
| 26 _bytesToWords(input, offset, len, m, 0, m_len); | |
| 27 | |
| 28 var l = len * 8; | |
| 29 var w = new List<int>(80); | |
| 30 var H0 = 0x67452301; | |
| 31 var H1 = 0xEFCDAB89; | |
| 32 var H2 = 0x98BADCFE; | |
| 33 var H3 = 0x10325476; | |
| 34 var H4 = 0xC3D2E1F0; | |
| 35 | |
| 36 // TODO(iposva): Deal with lengths longer than 32-bits once arrays can | |
| 37 // grow to this size. | |
| 38 m[l >> 5] |= 0x80 << (24 - l % 32); | |
| 39 m[(((l + 64) >> 9) << 4) + 15] = l; | |
| 40 | |
| 41 for (var i = 0; i < m_len; i += 16) { | |
| 42 var a = H0; | |
| 43 var b = H1; | |
| 44 var c = H2; | |
| 45 var d = H3; | |
| 46 var e = H4; | |
| 47 | |
| 48 for (var j = 0; j < 80; j++) { | |
| 49 if (j < 16) { | |
| 50 w[j] = m[i + j]; | |
| 51 } else { | |
| 52 var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16]; | |
| 53 w[j] = _rotl32(n, 1); | |
| 54 } | |
| 55 | |
| 56 var t = _rotl32(a, 5) + e + w[j]; | |
| 57 if (j < 20) { | |
| 58 t += (((b & c) | (~b & d)) + 0x5A827999); | |
| 59 } else if (j < 40) { | |
| 60 t += ((b ^ c ^ d) + 0x6ED9EBA1); | |
| 61 } else if (j < 60) { | |
| 62 t += (((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC); | |
| 63 } else { | |
| 64 t += ((b ^ c ^ d) + 0xCA62C1D6); | |
| 65 } | |
| 66 | |
| 67 e = d; | |
| 68 d = c; | |
| 69 c = _rotl32(b, 30); | |
| 70 b = a; | |
| 71 a = t & _MASK_32; | |
| 72 } | |
| 73 H0 = _add32(H0, a); | |
| 74 H1 = _add32(H1, b); | |
| 75 H2 = _add32(H2, c); | |
| 76 H3 = _add32(H3, d); | |
| 77 H4 = _add32(H4, e); | |
| 78 } | |
| 79 return _wordsToBytes([H0, H1, H2, H3, H4]); | |
| 80 } | 66 } |
| 81 | 67 |
| 82 static final int _BITS_PER_CHUNK = 512; | 68 List<int> _w; |
| 83 } | 69 } |
| 84 | |
| OLD | NEW |