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

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

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

Powered by Google App Engine
This is Rietveld 408576698