diff --git a/lib/crypto.dart b/lib/crypto.dart index 63b54e2..7648c2d 100644 --- a/lib/crypto.dart +++ b/lib/crypto.dart @@ -8,6 +8,7 @@ export 'src/base64.dart'; export 'src/base64/decoder.dart'; export 'src/base64/encoder.dart'; export 'src/crypto_utils.dart'; +export 'src/digest.dart'; export 'src/hash.dart'; export 'src/hmac.dart'; export 'src/md5.dart'; diff --git a/lib/src/digest.dart b/lib/src/digest.dart new file mode 100644 index 0000000..02af614 --- /dev/null +++ b/lib/src/digest.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2015, 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. + +library crypto.digest; + +import 'dart:typed_data'; + +import 'crypto_utils.dart'; + +/// A message digest as computed by a [Hash] or [HMAC] function. +class Digest { + /// The message digest as an array of bytes. + final List bytes; + + Digest(List bytes) + : bytes = new Uint8List.fromList(bytes); + + /// Returns whether this is equal to another digest. + /// + /// This should be used instead of manual comparisons to avoid leaking + /// information via timing. + bool operator ==(Object other) { + if (other is! Digest) return false; + if (other.bytes.length != bytes.length) return false; + + var result = 0; + for (var i = 0; i < bytes.length; i++) { + result |= bytes[i] ^ other.bytes[i]; + } + return result == 0; + } + + /// The message digest as a string of hexadecimal digits. + String toString() => CryptoUtils.bytesToHex(bytes); +}