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

Side by Side Diff: lib/crypto/hash_utils.dart

Issue 10351008: Implement md5 hash in crypto library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Indentation fix Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « lib/crypto/crypto.dart ('k') | lib/crypto/md5.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // Constants. 5 // Constants.
6 final _MASK_8 = 0xff; 6 final _MASK_8 = 0xff;
7 final _MASK_32 = 0xffffffff; 7 final _MASK_32 = 0xffffffff;
8 final _BITS_PER_BYTE = 8; 8 final _BITS_PER_BYTE = 8;
9 final _BYTES_PER_WORD = 4; 9 final _BYTES_PER_WORD = 4;
10 10
11 // Base class encapsulating common behavior for SHA cryptographic hash 11 // Helper functions used by more than one hasher.
12
13 // Rotate left limiting to unsigned 32-bit values.
14 int _rotl32(int val, int shift) {
15 var mod_shift = shift & 31;
16 return ((val << mod_shift) & _MASK_32) |
17 ((val & _MASK_32) >> (32 - mod_shift));
18 }
19
20 // Base class encapsulating common behavior for cryptographic hash
12 // functions. 21 // functions.
13 class _SHAHashBase implements Hash { 22 class _HashBase implements Hash {
14 _SHAHashBase(int this._chunkSizeInWords, int this._digestSizeInWords) 23 _HashBase(int this._chunkSizeInWords,
24 int this._digestSizeInWords,
25 bool this._bigEndianWords)
15 : _pendingData = [] { 26 : _pendingData = [] {
16 _currentChunk = new List(_chunkSizeInWords); 27 _currentChunk = new List(_chunkSizeInWords);
17 _h = new List(_digestSizeInWords); 28 _h = new List(_digestSizeInWords);
18 } 29 }
19 30
20 // Update the hasher with more data. 31 // Update the hasher with more data.
21 _SHAHashBase update(List<int> data) { 32 _HashBase update(List<int> data) {
22 if (_digestCalled) { 33 if (_digestCalled) {
23 throw new HashException( 34 throw new HashException(
24 'Hash update method called after digest was retrieved'); 35 'Hash update method called after digest was retrieved');
25 } 36 }
26 _lengthInBytes += data.length; 37 _lengthInBytes += data.length;
27 _pendingData.addAll(data); 38 _pendingData.addAll(data);
28 _iterate(); 39 _iterate();
29 return this; 40 return this;
30 } 41 }
31 42
(...skipping 29 matching lines...) Expand all
61 var result = []; 72 var result = [];
62 for (var i = 0; i < _h.length; i++) { 73 for (var i = 0; i < _h.length; i++) {
63 result.addAll(_wordToBytes(_h[i])); 74 result.addAll(_wordToBytes(_h[i]));
64 } 75 }
65 return result; 76 return result;
66 } 77 }
67 78
68 // Converts a list of bytes to a chunk of 32-bit words. 79 // Converts a list of bytes to a chunk of 32-bit words.
69 _bytesToChunk(List<int> data, int dataIndex) { 80 _bytesToChunk(List<int> data, int dataIndex) {
70 assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD)); 81 assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
82
71 for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) { 83 for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
72 var word = (data[dataIndex++] & 0xff) << 24; 84 var w3 = _bigEndianWords ? data[dataIndex] : data[dataIndex + 3];
73 word |= (data[dataIndex++] & _MASK_8) << 16; 85 var w2 = _bigEndianWords ? data[dataIndex + 1] : data[dataIndex + 2];
74 word |= (data[dataIndex++] & _MASK_8) << 8; 86 var w1 = _bigEndianWords ? data[dataIndex + 2] : data[dataIndex + 1];
75 word |= (data[dataIndex++] & _MASK_8); 87 var w0 = _bigEndianWords ? data[dataIndex + 3] : data[dataIndex];
88 dataIndex += 4;
89 var word = (w3 & 0xff) << 24;
90 word |= (w2 & _MASK_8) << 16;
91 word |= (w1 & _MASK_8) << 8;
92 word |= (w0 & _MASK_8);
76 _currentChunk[wordIndex] = word; 93 _currentChunk[wordIndex] = word;
77 } 94 }
78 } 95 }
79 96
80 // Convert a 32-bit word to four bytes. 97 // Convert a 32-bit word to four bytes.
81 _wordToBytes(int word) { 98 _wordToBytes(int word) {
82 List<int> bytes = new List(_BYTES_PER_WORD); 99 List<int> bytes = new List(_BYTES_PER_WORD);
83 bytes[0] = word >> 24; 100 bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
84 bytes[1] = (word >> 16) & _MASK_8; 101 bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
85 bytes[2] = (word >> 8) & _MASK_8; 102 bytes[2] = (word >> (_bigEndianWords ? 8 : 16)) & _MASK_8;
86 bytes[3] = word & _MASK_8; 103 bytes[3] = (word >> (_bigEndianWords ? 0 : 24)) & _MASK_8;
87 return bytes; 104 return bytes;
88 } 105 }
89 106
90 // Iterate through data updating the hash computation for each 107 // Iterate through data updating the hash computation for each
91 // chunk. 108 // chunk.
92 _iterate() { 109 _iterate() {
93 var len = _pendingData.length; 110 var len = _pendingData.length;
94 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD; 111 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
95 if (len >= chunkSizeInBytes) { 112 if (len >= chunkSizeInBytes) {
96 var index = 0; 113 var index = 0;
97 for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) { 114 for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) {
98 _bytesToChunk(_pendingData, index); 115 _bytesToChunk(_pendingData, index);
99 _updateHash(_currentChunk); 116 _updateHash(_currentChunk);
100 } 117 }
101 var remaining = len - index; 118 var remaining = len - index;
102 _pendingData = _pendingData.getRange(index, remaining); 119 _pendingData = _pendingData.getRange(index, remaining);
103 } 120 }
104 } 121 }
105 122
106 // Finalize the data. Add a 1 bit to the end of the message. Expand with 123 // Finalize the data. Add a 1 bit to the end of the message. Expand with
107 // 0 bits and the length of the message. 124 // 0 bits and add the length of the message.
108 _finalizeData() { 125 _finalizeData() {
109 _pendingData.add(0x80); 126 _pendingData.add(0x80);
110 var contentsLength = _lengthInBytes + 9; 127 var contentsLength = _lengthInBytes + 9;
111 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD; 128 var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
112 var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes); 129 var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes);
113 var zeroPadding = finalizedLength - contentsLength; 130 var zeroPadding = finalizedLength - contentsLength;
114 for (var i = 0; i < zeroPadding; i++) { 131 for (var i = 0; i < zeroPadding; i++) {
115 _pendingData.add(0); 132 _pendingData.add(0);
116 } 133 }
117 var lengthInBits = _lengthInBytes * _BITS_PER_BYTE; 134 var lengthInBits = _lengthInBytes * _BITS_PER_BYTE;
118 _pendingData.addAll(_wordToBytes(lengthInBits >> 32)); 135 if (_bigEndianWords) {
119 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32)); 136 _pendingData.addAll(_wordToBytes(lengthInBits >> 32));
137 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
138 } else {
139 _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
140 _pendingData.addAll(_wordToBytes(lengthInBits >> 32));
141 }
120 } 142 }
121 143
122 // Hasher state. 144 // Hasher state.
123 final int _chunkSizeInWords; 145 final int _chunkSizeInWords;
124 final int _digestSizeInWords; 146 final int _digestSizeInWords;
147 final bool _bigEndianWords;
125 int _lengthInBytes = 0; 148 int _lengthInBytes = 0;
126 List<int> _pendingData; 149 List<int> _pendingData;
127 List<int> _currentChunk; 150 List<int> _currentChunk;
128 List<int> _h; 151 List<int> _h;
129 bool _digestCalled = false; 152 bool _digestCalled = false;
130 } 153 }
OLDNEW
« no previous file with comments | « lib/crypto/crypto.dart ('k') | lib/crypto/md5.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698