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

Unified Diff: lib/crypto/sha_utils.dart

Issue 10134055: Add common interface for cryptographic hash functions to lib/crypto.dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: lib/crypto/sha_utils.dart
diff --git a/lib/crypto/sha_utils.dart b/lib/crypto/sha_utils.dart
new file mode 100644
index 0000000000000000000000000000000000000000..082d9f2b292e92d603bab2b5fad6cdeb4d5d80fd
--- /dev/null
+++ b/lib/crypto/sha_utils.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Constants.
+final _MASK_8 = 0xff;
+final _MASK_32 = 0xffffffff;
+final _BITS_PER_BYTE = 8;
+final _BYTES_PER_WORD = 4;
+
+// Base class encapsulating common behavior for SHA cryptographic hash
+// functions.
+class _SHACryptoHashBase implements CryptoHash {
+ _SHACryptoHashBase(int this._chunkSizeInWords, int this._digestSizeInWords)
+ : _pendingData = [] {
+ _currentChunk = new List(_chunkSizeInWords);
+ _h = new List(_digestSizeInWords);
+ }
+
+ // Update the hasher with more data.
+ _SHACryptoHashBase update(List<int> data) {
+ _lengthInBytes += data.length;
+ _pendingData.addAll(data);
+ _iterate();
+ return this;
+ }
+
+ // Finish the hash computation and return the digest string.
+ List<int> digest() {
+ _finalizeData();
+ _iterate();
+ assert(_pendingData.length == 0);
+ var result = [];
+ for (var i = 0; i < _h.length; i++) {
+ result.addAll(_wordToBytes(_h[i]));
+ }
+ return result;
+ }
+
+ // One round of the hash computation.
+ abstract _updateHash(List<int> m);
+
+ // Helper methods.
+ _add32(x, y) => (x + y) & _MASK_32;
+ _roundUp(val, n) => (val + n - 1) & -n;
+
+ // Converts a list of bytes to a chunk of 32-bit words.
+ _bytesToChunk(List<int> data, int dataIndex) {
+ assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
+ for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
+ var word = (data[dataIndex++] & 0xff) << 24;
+ word |= (data[dataIndex++] & _MASK_8) << 16;
+ word |= (data[dataIndex++] & _MASK_8) << 8;
+ word |= (data[dataIndex++] & _MASK_8);
+ _currentChunk[wordIndex] = word;
+ }
+ }
+
+ // Convert a 32-bit word to four bytes.
+ _wordToBytes(int word) {
+ List<int> bytes = new List(_BYTES_PER_WORD);
+ bytes[0] = word >> 24;
+ bytes[1] = (word >> 16) & _MASK_8;
+ bytes[2] = (word >> 8) & _MASK_8;
+ bytes[3] = word & _MASK_8;
+ return bytes;
+ }
+
+ // Iterate through data updating the hash computation for each
+ // chunk.
+ _iterate() {
+ var len = _pendingData.length;
+ var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
+ if (len >= chunkSizeInBytes) {
+ var index = 0;
+ for (; (len - index) >= chunkSizeInBytes; index += chunkSizeInBytes) {
+ _bytesToChunk(_pendingData, index);
+ _updateHash(_currentChunk);
+ }
+ var remaining = len - index;
+ _pendingData = _pendingData.getRange(index, remaining);
+ }
+ }
+
+ // Finalize the data. Add a 1 bit to the end of the message. Expand with
+ // 0 bits and the length of the message.
+ _finalizeData() {
+ _pendingData.add(0x80);
+ var contentsLength = _lengthInBytes + 9;
+ var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
+ var finalizedLength = _roundUp(contentsLength, chunkSizeInBytes);
+ var zeroPadding = finalizedLength - contentsLength;
+ for (var i = 0; i < zeroPadding; i++) {
+ _pendingData.add(0);
+ }
+ var lengthInBits = _lengthInBytes * _BITS_PER_BYTE;
+ _pendingData.addAll(_wordToBytes(lengthInBits >> 32));
+ _pendingData.addAll(_wordToBytes(lengthInBits & _MASK_32));
+ }
+
+ // Hasher state.
+ int _lengthInBytes = 0;
+ int _chunkSizeInWords;
+ int _digestSizeInWords;
+ List<int> _pendingData;
+ List<int> _currentChunk;
+ List<int> _h;
+}

Powered by Google App Engine
This is Rietveld 408576698