Use the recommended name for analysis_options

And add/fix a number of standard lints
diff --git a/.analysis_options b/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..092773b
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,29 @@
+analyzer:
+ strong-mode: true
+linter:
+  rules:
+     # Errors
+     - avoid_empty_else
+     - comment_references
+     - control_flow_in_finally
+     - empty_statements
+     - hash_and_equals
+     - test_types_in_equals
+     - throw_in_finally
+     - unrelated_type_equality_checks
+     - valid_regexps
+
+     # Style
+     - annotate_overrides
+     - avoid_init_to_null
+     - avoid_return_types_on_setters
+     - await_only_futures
+     - camel_case_types
+     - empty_catches
+     - empty_constructor_bodies
+     - library_names
+     - library_prefixes
+     - non_constant_identifier_names
+     - prefer_is_not_empty
+     - slash_for_doc_comments
+     - type_init_formals
diff --git a/lib/src/digest.dart b/lib/src/digest.dart
index b7fbcc5..1ba4762 100644
--- a/lib/src/digest.dart
+++ b/lib/src/digest.dart
@@ -5,7 +5,7 @@
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
 
-/// A message digest as computed by a [Hash] or [HMAC] function.
+/// A message digest as computed by a `Hash` or `HMAC` function.
 class Digest {
   /// The message digest as an array of bytes.
   final List<int> bytes;
@@ -16,11 +16,14 @@
   ///
   /// This should be used instead of manual comparisons to avoid leaking
   /// information via timing.
+  @override
   bool operator ==(Object other) =>
       other is Digest && const ListEquality().equals(bytes, other.bytes);
 
+  @override
   int get hashCode => const ListEquality().hash(bytes);
 
   /// The message digest as a string of hexadecimal digits.
+  @override
   String toString() => hex.encode(bytes);
 }
diff --git a/lib/src/digest_sink.dart b/lib/src/digest_sink.dart
index 7f6502a..48c85f5 100644
--- a/lib/src/digest_sink.dart
+++ b/lib/src/digest_sink.dart
@@ -4,7 +4,7 @@
 
 import 'digest.dart';
 
-/// A sink used to get a digest value out of [Hash.startChunkedConversion].
+/// A sink used to get a digest value out of `Hash.startChunkedConversion`.
 class DigestSink extends Sink<Digest> {
   /// The value added to the sink, if any.
   Digest get value {
@@ -17,11 +17,13 @@
   /// Adds [value] to the sink.
   ///
   /// Unlike most sinks, this may only be called once.
+  @override
   void add(Digest value) {
     assert(_value == null);
     _value = value;
   }
 
+  @override
   void close() {
     assert(_value != null);
   }
diff --git a/lib/src/hash.dart b/lib/src/hash.dart
index fad44ae..14a2de6 100644
--- a/lib/src/hash.dart
+++ b/lib/src/hash.dart
@@ -15,12 +15,13 @@
 abstract class Hash extends Converter<List<int>, Digest> {
   /// The internal block size of the hash in bytes.
   ///
-  /// This is exposed for use by the [Hmac] class, which needs to know the block
+  /// This is exposed for use by the `Hmac` class, which needs to know the block
   /// size for the [Hash] it uses.
   int get blockSize;
 
   const Hash();
 
+  @override
   Digest convert(List<int> data) {
     var innerSink = new DigestSink();
     var outerSink = startChunkedConversion(innerSink);
@@ -29,5 +30,6 @@
     return innerSink.value;
   }
 
+  @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink);
 }
diff --git a/lib/src/hash_sink.dart b/lib/src/hash_sink.dart
index e1c9400..9d70746 100644
--- a/lib/src/hash_sink.dart
+++ b/lib/src/hash_sink.dart
@@ -51,10 +51,11 @@
   /// Runs a single iteration of the hash computation, updating [digest] with
   /// the result.
   ///
-  /// [m] is the current chunk, whose size is given by the `chunkSizeInWords`
-  /// parameter passed to the constructor.
+  /// [chunk] is the current chunk, whose size is given by the
+  /// `chunkSizeInWords` parameter passed to the constructor.
   void updateHash(Uint32List chunk);
 
+  @override
   void add(List<int> data) {
     if (_isClosed) throw new StateError('Hash.add() called after close().');
     _lengthInBytes += data.length;
@@ -62,6 +63,7 @@
     _iterate();
   }
 
+  @override
   void close() {
     if (_isClosed) return;
     _isClosed = true;
diff --git a/lib/src/hmac.dart b/lib/src/hmac.dart
index f5bf6bf..5caed75 100644
--- a/lib/src/hmac.dart
+++ b/lib/src/hmac.dart
@@ -22,7 +22,7 @@
   /// The secret key shared by the sender and the receiver.
   final Uint8List _key;
 
-  /// Create an [HMAC] object from a [Hash] and a binary key.
+  /// 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.
@@ -37,6 +37,7 @@
     _key.setRange(0, key.length, key);
   }
 
+  @override
   Digest convert(List<int> data) {
     var innerSink = new DigestSink();
     var outerSink = startChunkedConversion(innerSink);
@@ -45,6 +46,7 @@
     return innerSink.value;
   }
 
+  @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       new _HmacSink(sink, _hash, _key);
 }
@@ -81,16 +83,19 @@
     _innerSink.add(padding);
   }
 
+  @override
   void add(List<int> data) {
     if (_isClosed) throw new StateError("HMAC is closed");
     _innerSink.add(data);
   }
 
+  @override
   void addSlice(List<int> data, int start, int end, bool isLast) {
     if (_isClosed) throw new StateError("HMAC is closed");
     _innerSink.addSlice(data, start, end, isLast);
   }
 
+  @override
   void close() {
     if (_isClosed) return;
     _isClosed = true;
diff --git a/lib/src/md5.dart b/lib/src/md5.dart
index adcf7c1..f666ef1 100644
--- a/lib/src/md5.dart
+++ b/lib/src/md5.dart
@@ -30,10 +30,12 @@
 /// Note that it's almost always easier to use [md5] rather than creating a new
 /// instance.
 class MD5 extends Hash {
+  @override
   final int blockSize = 16 * bytesPerWord;
 
   MD5._();
 
+  @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       new ByteConversionSink.from(new _MD5Sink(sink));
 }
@@ -64,9 +66,10 @@
 
 /// The concrete implementation of [MD5].
 ///
-/// This is separate so that it can extend [HashBase] without leaking additional
-/// public memebers.
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
 class _MD5Sink extends HashSink {
+  @override
   final digest = new Uint32List(4);
 
   _MD5Sink(Sink<Digest> sink)
@@ -77,6 +80,7 @@
     digest[3] = 0x10325476;
   }
 
+  @override
   void updateHash(Uint32List chunk) {
     assert(chunk.length == 16);
 
diff --git a/lib/src/sha1.dart b/lib/src/sha1.dart
index f0b64fc..dd40410 100644
--- a/lib/src/sha1.dart
+++ b/lib/src/sha1.dart
@@ -21,19 +21,22 @@
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc3174
 class Sha1 extends Hash {
+  @override
   final int blockSize = 16 * bytesPerWord;
 
   Sha1._();
 
+  @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       new ByteConversionSink.from(new _Sha1Sink(sink));
 }
 
 /// The concrete implementation of [Sha1].
 ///
-/// This is separate so that it can extend [HashBase] without leaking additional
+/// This is separate so that it can extend [HashSink] without leaking additional
 /// public memebers.
 class _Sha1Sink extends HashSink {
+  @override
   final digest = new Uint32List(5);
 
   /// The sixteen words from the original chunk, extended to 80 words.
@@ -52,6 +55,7 @@
     digest[4] = 0xC3D2E1F0;
   }
 
+  @override
   void updateHash(Uint32List chunk) {
     assert(chunk.length == 16);
 
diff --git a/lib/src/sha256.dart b/lib/src/sha256.dart
index 5c6c968..90c8002 100644
--- a/lib/src/sha256.dart
+++ b/lib/src/sha256.dart
@@ -24,12 +24,14 @@
 /// Note that it's almost always easier to use [sha256] rather than creating a
 /// new instance.
 class Sha256 extends Hash {
+  @override
   final int blockSize = 16 * bytesPerWord;
 
   Sha256._();
 
   Sha256 newInstance() => new Sha256._();
 
+  @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       new ByteConversionSink.from(new _Sha256Sink(sink));
 }
@@ -51,9 +53,10 @@
 
 /// The concrete implementation of [Sha256].
 ///
-/// This is separate so that it can extend [HashBase] without leaking additional
-/// public memebers.
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
 class _Sha256Sink extends HashSink {
+  @override
   final digest = new Uint32List(8);
 
   /// The sixteen words from the original chunk, extended to 64 words.
@@ -88,6 +91,7 @@
   int _ssig0(int x) => _rotr32(7, x) ^ _rotr32(18, x) ^ (x >> 3);
   int _ssig1(int x) => _rotr32(17, x) ^ _rotr32(19, x) ^ (x >> 10);
 
+  @override
   void updateHash(Uint32List chunk) {
     assert(chunk.length == 16);