Update deprecations.

This deprecates:

* Classes that used the wrong capitalization.
* Base64 APIs, which are now available in the core libraries.
* CryptoUtils, whose functionality is now available in the core
  libraries and the convert package.

It also updates the deprecation message in already-deprecated APIs to
correspond to only mention the version in which the APIs will be
removed. The alternative APIs are mentioned in doc comments instead.

R=rnystrom@google.com

Review URL: https://codereview.chromium.org//1826543003 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8efbd20..0d97adc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@
   `Hash.startChunkedConversion`—should be used in preference to the old APIs,
   which are now deprecated.
 
+* `SHA1`, `SHA256`, and `HMAC` have been renamed to `Sha1`, `Sha256`, and
+  `Hmac`, respectively. The old names still work, but are deprecated.
+
 * Top-level `sha1`, `sha256`, and `md5` fields have been added to make it easier
   to use those hash algorithms without having to instantiate new instances.
 
@@ -17,8 +20,20 @@
   `Hash.convert` should be used for hashing single values, and
   `Hash.startChunkedConversion` should be used for hashing streamed values.
   
-* `new SHA1()`, `new SHA256()`, and `new MD5()` are deprecated. Use the
-  top-level `sha1`, `sha256`, and `md5` fields instead.
+* `SHA1` and `SHA256` are deprecated. Use the top-level `sha1` and `sha256`
+  fields instead.
+
+* While the `MD5` class is not deprecated, the `new MD5()` constructor is. Use
+  the top-level `md5` field instead.
+
+* `HMAC` is deprecated. Use `Hmac` instead.
+
+* `Base64Codec`, `Base64Encoder`, `Base64Decoder`, `Base64EncoderSink`,
+  `Base64DecoderSink`, and `BASE64` are deprecated. Use the Base64 APIs in
+  `dart:convert` instead.
+
+* `CryptoUtils` is deprecated. Use the Base64 APIs in `dart:convert` and the hex
+  APIs in the `convert` package instead.
 
 ## 0.9.1
 
diff --git a/lib/src/base64.dart b/lib/src/base64.dart
index 9bea383..91d672b 100644
--- a/lib/src/base64.dart
+++ b/lib/src/base64.dart
@@ -7,14 +7,16 @@
 import 'base64/decoder.dart';
 import 'base64/encoder.dart';
 
-/// An instance of the default implementation of [Base64Codec].
+/// This is deprecated.
 ///
-/// This provides convenient access to most common Base64 use-cases.
+/// Use the `BASE64` constant in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 const Base64Codec BASE64 = const Base64Codec();
 
-/// A codec that converts between binary data and [Base64][rfc]-encoded strings.
+/// This is deprecated.
 ///
-/// [rfc]: https://tools.ietf.org/html/rfc4648
+/// Use the `Base64Codec` class in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 class Base64Codec extends Codec<List<int>, String> {
   final bool _urlSafe;
   final bool _addLineSeparator;
diff --git a/lib/src/base64/decoder.dart b/lib/src/base64/decoder.dart
index 19b3cf4..8f22a99 100644
--- a/lib/src/base64/decoder.dart
+++ b/lib/src/base64/decoder.dart
@@ -24,9 +24,10 @@
   38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
 ];
 
-/// An encoder that converts [Base64][rfc] strings to sequences of bytes.
+/// This is deprecated.
 ///
-/// [rfc]: https://tools.ietf.org/html/rfc4648
+/// Use the `Base64Decoder` class in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 class Base64Decoder extends Converter<String, List<int>> {
   const Base64Decoder();
 
diff --git a/lib/src/base64/decoder_sink.dart b/lib/src/base64/decoder_sink.dart
index 3fbf8fc..0a09a82 100644
--- a/lib/src/base64/decoder_sink.dart
+++ b/lib/src/base64/decoder_sink.dart
@@ -6,7 +6,10 @@
 
 import 'decoder.dart';
 
-/// A [ChunkedConversionSink] for decoding chunks of Base64 strings to data.
+/// This is deprecated.
+///
+/// Use the `Base64Decoder` class in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 class Base64DecoderSink extends ChunkedConversionSink<String> {
   /// The encoder used to decode each chunk.
   final Base64Decoder _decoder = new Base64Decoder();
diff --git a/lib/src/base64/encoder.dart b/lib/src/base64/encoder.dart
index 7d688fc..bdbf6d8 100644
--- a/lib/src/base64/encoder.dart
+++ b/lib/src/base64/encoder.dart
@@ -25,9 +25,10 @@
 /// The line length for Base64 strings with line separators.
 const _lineLength = 76;
 
-/// An encoder that converts sequences of bytes to strings using [Base64][rfc].
+/// This is deprecated.
 ///
-/// [rfc]: https://tools.ietf.org/html/rfc4648
+/// Use the `Base64Encoder` class in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 class Base64Encoder extends Converter<List<int>, String> {
   /// Whether this encoder generates URL-safe strings.
   final bool _urlSafe;
diff --git a/lib/src/base64/encoder_sink.dart b/lib/src/base64/encoder_sink.dart
index 3ba393b..293735b 100644
--- a/lib/src/base64/encoder_sink.dart
+++ b/lib/src/base64/encoder_sink.dart
@@ -6,7 +6,10 @@
 
 import 'encoder.dart';
 
-/// A [ChunkedConversionSink] for encoding chunks of data to Base64.
+/// This is deprecated.
+///
+/// Use the `Base64Encoder` class in `dart:convert` instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
 class Base64EncoderSink extends ChunkedConversionSink<List<int>> {
   /// The encoder used to encode each chunk.
   final Base64Encoder _encoder;
diff --git a/lib/src/crypto_utils.dart b/lib/src/crypto_utils.dart
index bcb8d03..4af507c 100644
--- a/lib/src/crypto_utils.dart
+++ b/lib/src/crypto_utils.dart
@@ -4,10 +4,12 @@
 
 import 'base64.dart';
 
-/// Utility methods for working with message digests.
+/// This class is deprecated.
+@Deprecated("Will be removed in crypto 1.0.0.")
 abstract class CryptoUtils {
-  /// Convert a list of bytes (for example a message digest) into a hexadecimal
-  /// string.
+  /// This is deprecated.
+  ///
+  /// Use `hex` from `package:convert` instead.
   static String bytesToHex(List<int> bytes) {
     var result = new StringBuffer();
     for (var part in bytes) {
@@ -16,30 +18,16 @@
     return result.toString();
   }
 
-  /// Converts a list of bytes into a [Base64-encoded][rfc] string.
+  /// This is deprecated.
   ///
-  /// [rfc]: https://tools.ietf.org/html/rfc4648
-  ///
-  /// The list can be any list of integers from 0 to 255 inclusive, for example
-  /// a message digest.
-  ///
-  /// If [addLineSeparator] is true, the resulting string will  be
-  /// broken into lines of 76 characters, separated by "\r\n".
-  ///
-  /// If [urlSafe] is true, the resulting string will be URL- and filename-
-  /// safe.
+  /// Use `BASE64` from `dart:convert` instead.
   static String bytesToBase64(List<int> bytes,
           {bool urlSafe: false, bool addLineSeparator: false}) =>
       BASE64.encode(bytes,
           urlSafe: urlSafe, addLineSeparator: addLineSeparator);
 
-  /// Converts a [Base64-encoded][rfc] String into list of bytes.
+  /// This is deprecated.
   ///
-  /// [rfc]: https://tools.ietf.org/html/rfc4648
-  ///
-  /// This ignores "\r\n" sequences in [input]. It accepts both URL-safe and
-  /// -unsafe Base 64 encoded strings.
-  ///
-  /// Throws a [FormatException] if [input] contains invalid characters.
+  /// Use `BASE64` from `dart:convert` instead.
   static List<int> base64StringToBytes(String input) => BASE64.decode(input);
 }
diff --git a/lib/src/digest.dart b/lib/src/digest.dart
index 44b8379..2e92fe2 100644
--- a/lib/src/digest.dart
+++ b/lib/src/digest.dart
@@ -2,7 +2,7 @@
 // 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.
 
-import 'crypto_utils.dart';
+import 'package:convert/convert.dart';
 
 /// A message digest as computed by a [Hash] or [HMAC] function.
 class Digest {
@@ -29,5 +29,5 @@
   }
 
   /// The message digest as a string of hexadecimal digits.
-  String toString() => CryptoUtils.bytesToHex(bytes);
+  String toString() => hex.encode(bytes);
 }
diff --git a/lib/src/hash.dart b/lib/src/hash.dart
index 2013ca6..9714f42 100644
--- a/lib/src/hash.dart
+++ b/lib/src/hash.dart
@@ -40,21 +40,22 @@
 
   ByteConversionSink startChunkedConversion(Sink<Digest> sink);
 
-  /// Returns a new instance of this hash function.
-  @Deprecated("Expires in 1.0.0. Use Hash.startChunkedConversion() instead.")
+  /// This is deprecated.
+  ///
+  /// Use [startChunkedConversion] instead.
+  @Deprecated("Will be removed in crypto 1.0.0.")
   Hash newInstance();
 
-  /// Add a list of bytes to the hash computation.
+  /// This is deprecated.
   ///
-  /// If [this] has already been closed, throws a [StateError].
-  @Deprecated("Expires in 1.0.0. Use Hash.convert() or "
-      "Hash.startChunkedConversion() instead.")
+  /// Use [convert] or [startChunkedConversion] instead.
+  @Deprecated("Will be removed in crypto 1.0.0.")
   void add(List<int> data) => _sink.add(data);
 
-  /// Finish the hash computation and extract the message digest as a list of
-  /// bytes.
-  @Deprecated("Expires in 1.0.0. Use Hash.convert() or "
-      "Hash.startChunkedConversion() instead.")
+  /// This is deprecated.
+  ///
+  /// Use [convert] or [startChunkedConversion] instead.
+  @Deprecated("Will be removed in crypto 1.0.0.")
   List<int> close() {
     _sink.close();
     return _innerSink.value.bytes;
diff --git a/lib/src/hmac.dart b/lib/src/hmac.dart
index 8d86797..f1b9de2 100644
--- a/lib/src/hmac.dart
+++ b/lib/src/hmac.dart
@@ -17,28 +17,18 @@
 ///
 /// HMAC allows messages to be cryptographically authenticated using any
 /// iterated cryptographic hash function.
-class HMAC extends Converter<List<int>, Digest> {
+class Hmac extends Converter<List<int>, Digest> {
   /// The hash function used to compute the authentication digest.
   final Hash _hash;
 
   /// The secret key shared by the sender and the receiver.
   final Uint8List _key;
 
-  /// The bytes from the message so far.
-  final _message = new Uint8Buffer();
-
-  /// The sink for implementing the deprecated APIs that involved adding data
-  /// directly to the [HMAC] instance.
-  _HmacSink _sink;
-
-  /// The sink that [_sink] sends the [Digest] to once it finishes hashing.
-  DigestSink _innerSink;
-
   /// Create an [HMAC] object from a [Hash] and a binary key.
   ///
   /// The key should be a secret shared between the sender and receiver of the
   /// message.
-  HMAC(Hash hash, List<int> key)
+  Hmac(Hash hash, List<int> key)
       : _hash = hash,
         _key = new Uint8List(hash.blockSize) {
     // Hash the key if it's longer than the block size of the hash.
@@ -47,9 +37,6 @@
     // If [key] is shorter than the block size, the rest of [_key] will be
     // 0-padded.
     _key.setRange(0, key.length, key);
-
-    _innerSink = new DigestSink();
-    _sink = startChunkedConversion(_innerSink);
   }
 
   Digest convert(List<int> data) {
@@ -62,30 +49,44 @@
 
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       new _HmacSink(sink, _hash, _key);
+}
 
-  /// Adds a list of bytes to the message.
+/// This is deprecated.
+///
+/// Use [Hmac] instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
+class HMAC {
+  final Hmac _hmac;
+
+  /// The sink for implementing the deprecated APIs that involved adding data
+  /// directly to the [HMAC] instance.
+  _HmacSink _sink;
+
+  /// The sink that [_sink] sends the [Digest] to once it finishes hashing.
+  DigestSink _innerSink;
+
+  /// The bytes from the message so far.
+  final _message = new Uint8Buffer();
+
+  /// Create an [HMAC] object from a [Hash] and a binary key.
   ///
-  /// If [this] has already been closed, throws a [StateError].
-  @Deprecated("Expires in 1.0.0. Use HMAC.convert() or "
-      "HMAC.startChunkedConversion() instead.")
+  /// The key should be a secret shared between the sender and receiver of the
+  /// message.
+  HMAC(Hash hash, List<int> key) : _hmac = new Hmac(hash, key) {
+    _innerSink = new DigestSink();
+    _sink = _hmac.startChunkedConversion(_innerSink);
+  }
+
   void add(List<int> data) {
     _message.addAll(data);
     _sink.add(data);
   }
 
-  /// Closes [this] and returns the digest of the message as a list of bytes.
-  ///
-  /// Once closed, [add] may no longer be called.
-  @Deprecated("Expires in 1.0.0. Use HMAC.convert() or "
-      "HMAC.startChunkedConversion() instead.")
   List<int> close() {
     _sink.close();
     return _innerSink.value.bytes;
   }
 
-  /// Returns the digest of the message so far, as a list of bytes.
-  @Deprecated("Expires in 1.0.0. Use HMAC.convert() or "
-      "HMAC.startChunkedConversion() instead.")
   List<int> get digest {
     if (_sink._isClosed) return _innerSink.value.bytes;
 
@@ -97,27 +98,18 @@
     var bytes = _innerSink.value.bytes;
 
     _innerSink = new DigestSink();
-    _sink = _hash.startChunkedConversion(_innerSink);
+    _sink = _hmac._hash.startChunkedConversion(_innerSink);
     _sink.add(_message);
 
     return bytes;
   }
 
-  /// Returns whether the digest computed for the data so far matches the given
-  /// [digest].
-  ///
-  /// This method should be used instead of iterative comparisons to avoid
-  /// leaking information via timing.
-  ///
-  /// Throws an [ArgumentError] if the given digest does not have the same size
-  /// as the digest computed by [this].
-  @Deprecated("Expires in 1.0.0. Use Digest.==() instead.")
   bool verify(List<int> digest) {
     var computedDigest = this.digest;
     if (digest.length != computedDigest.length) {
       throw new ArgumentError(
           'Invalid digest size: ${digest.length} in HMAC.verify. '
-          'Expected: ${_hash.blockSize}.');
+          'Expected: ${_hmac._hash.blockSize}.');
     }
 
     var result = 0;
diff --git a/lib/src/md5.dart b/lib/src/md5.dart
index 9f0da30..1374df7 100644
--- a/lib/src/md5.dart
+++ b/lib/src/md5.dart
@@ -32,7 +32,10 @@
 class MD5 extends Hash {
   final int blockSize = 16 * bytesPerWord;
 
-  @Deprecated("Use the md5 field instead.")
+  /// This constructor is deprecated.
+  ///
+  /// Use [md5] instead.
+  @Deprecated("Will be removed in crypto 1.0.0.")
   MD5();
 
   MD5 newInstance() => new MD5();
diff --git a/lib/src/sha1.dart b/lib/src/sha1.dart
index 008d2a9..9bb6411 100644
--- a/lib/src/sha1.dart
+++ b/lib/src/sha1.dart
@@ -10,36 +10,42 @@
 import 'hash_sink.dart';
 import 'utils.dart';
 
-/// An instance of [SHA1].
+/// An instance of [Sha1].
 ///
-/// This instance provides convenient access to the [SHA1][rfc] hash function.
+/// This instance provides convenient access to the [SHA-1][rfc] hash function.
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc3174
-final sha1 = new SHA1();
+final sha1 = new Sha1._();
 
 /// An implementation of the [SHA-1][rfc] hash function.
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc3174
-///
-/// Note that it's almost always easier to use [sha1] rather than creating a new
-/// instance.
-class SHA1 extends Hash {
+class Sha1 extends Hash {
   final int blockSize = 16 * bytesPerWord;
 
-  @Deprecated("Use the sha1 field instead.")
-  SHA1();
+  Sha1._();
 
-  SHA1 newInstance() => new SHA1();
+  Sha1 newInstance() => new Sha1._();
 
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
-      new ByteConversionSink.from(new _SHA1Sink(sink));
+      new ByteConversionSink.from(new _Sha1Sink(sink));
 }
 
-/// The concrete implementation of [SHA1].
+/// This class is deprecated.
+///
+/// Use [sha1] instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
+class SHA1 extends Sha1 {
+  SHA1() : super._();
+
+  SHA1 newInstance() => new SHA1();
+}
+
+/// The concrete implementation of [Sha1].
 ///
 /// This is separate so that it can extend [HashBase] without leaking additional
 /// public memebers.
-class _SHA1Sink extends HashSink {
+class _Sha1Sink extends HashSink {
   final digest = new Uint32List(5);
 
   /// The sixteen words from the original chunk, extended to 80 words.
@@ -48,7 +54,7 @@
   /// used across invocations of [updateHash].
   final Uint32List _extended;
 
-  _SHA1Sink(Sink<Digest> sink)
+  _Sha1Sink(Sink<Digest> sink)
       : _extended = new Uint32List(80),
         super(sink, 16) {
     digest[0] = 0x67452301;
diff --git a/lib/src/sha256.dart b/lib/src/sha256.dart
index e4ad757..61cd72f 100644
--- a/lib/src/sha256.dart
+++ b/lib/src/sha256.dart
@@ -10,12 +10,12 @@
 import 'hash_sink.dart';
 import 'utils.dart';
 
-/// An instance of [SHA256].
+/// An instance of [Sha256].
 ///
-/// This instance provides convenient access to the [SHA256][rfc] hash function.
+/// This instance provides convenient access to the [Sha256][rfc] hash function.
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc6234
-final sha256 = new SHA256();
+final sha256 = new Sha256._();
 
 /// An implementation of the [SHA-256][rfc] hash function.
 ///
@@ -23,16 +23,25 @@
 ///
 /// Note that it's almost always easier to use [sha256] rather than creating a
 /// new instance.
-class SHA256 extends Hash {
+class Sha256 extends Hash {
   final int blockSize = 16 * bytesPerWord;
 
-  @Deprecated("Use the sha256 field instead.")
-  SHA256();
+  Sha256._();
 
-  SHA256 newInstance() => new SHA256();
+  Sha256 newInstance() => new Sha256._();
 
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
-      new ByteConversionSink.from(new _SHA256Sink(sink));
+      new ByteConversionSink.from(new _Sha256Sink(sink));
+}
+
+/// This class is deprecated.
+///
+/// Use [sha256] instead.
+@Deprecated("Will be removed in crypto 1.0.0.")
+class SHA256 extends Sha256 {
+  SHA256() : super._();
+
+  SHA256 newInstance() => new SHA256();
 }
 
 /// Data from a non-linear function that functions as reproducible noise.
@@ -50,11 +59,11 @@
   0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 ];
 
-/// The concrete implementation of [SHA256].
+/// The concrete implementation of [Sha256].
 ///
 /// This is separate so that it can extend [HashBase] without leaking additional
 /// public memebers.
-class _SHA256Sink extends HashSink {
+class _Sha256Sink extends HashSink {
   final digest = new Uint32List(8);
 
   /// The sixteen words from the original chunk, extended to 64 words.
@@ -63,7 +72,7 @@
   /// used across invocations of [updateHash].
   final Uint32List _extended;
 
-  _SHA256Sink(Sink<Digest> sink)
+  _Sha256Sink(Sink<Digest> sink)
       : _extended = new Uint32List(64),
         super(sink, 16) {
     // Initial value of the hash parts. First 32 bits of the fractional parts
diff --git a/pubspec.yaml b/pubspec.yaml
index 800a115..16be73c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,12 @@
 name: crypto
-version: 0.9.2-dev
+version: 0.9.2
 author: Dart Team <misc@dartlang.org>
 description: Library of cryptographic functions.
 homepage: https://www.github.com/dart-lang/crypto
 environment:
   sdk: '>=1.8.0 <2.0.0'
 dependencies:
+  convert: '^1.0.0'
   charcode: '^1.1.0'
   typed_data: '^1.0.0'
 dev_dependencies:
diff --git a/test/hmac_md5_test.dart b/test/hmac_md5_test.dart
index f1fae7c..f1fcab3 100644
--- a/test/hmac_md5_test.dart
+++ b/test/hmac_md5_test.dart
@@ -11,7 +11,7 @@
   group("standard vector", () {
     for (var i = 0; i < _inputs.length; i++) {
       test(_macs[i], () {
-        expectHmacEquals(new MD5(), _inputs[i], _keys[i], _macs[i]);
+        expectHmacEquals(md5, _inputs[i], _keys[i], _macs[i]);
       });
     }
   });
diff --git a/test/hmac_sha1_test.dart b/test/hmac_sha1_test.dart
index 9f4a510..c7fc66d 100644
--- a/test/hmac_sha1_test.dart
+++ b/test/hmac_sha1_test.dart
@@ -12,7 +12,7 @@
   group("standard vector", () {
     for (var i = 0; i < _inputs.length; i++) {
       test(_macs[i], () {
-        expectHmacEquals(new SHA1(), _inputs[i], _keys[i], _macs[i]);
+        expectHmacEquals(sha1, _inputs[i], _keys[i], _macs[i]);
       });
     }
   });
diff --git a/test/hmac_sha256_test.dart b/test/hmac_sha256_test.dart
index 904a7f0..65fa419 100644
--- a/test/hmac_sha256_test.dart
+++ b/test/hmac_sha256_test.dart
@@ -12,7 +12,7 @@
   group("standard vector", () {
     for (var i = 0; i < _inputs.length; i++) {
       test(_macs[i], () {
-        expectHmacEquals(new SHA256(), _inputs[i], _keys[i], _macs[i]);
+        expectHmacEquals(sha256, _inputs[i], _keys[i], _macs[i]);
       });
     }
   });
diff --git a/test/utils.dart b/test/utils.dart
index 82b9f8a..dee342a 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -10,6 +10,6 @@
 
 /// Asserts that an HMAC using [hash] returns [mac] for [input] and [key].
 void expectHmacEquals(Hash hash, List<int> input, List<int> key, String mac) {
-  var hmac = new HMAC(hash, key);
+  var hmac = new Hmac(hash, key);
   expect(hmac.convert(input).toString(), startsWith(mac));
 }