Adds FIPS 180-4 512/t variants (#75)

* Adds FIPS 180-4 512/t variants

512/224 and 512/256 are variants specified in the FIPS 180-4 and
commonly available in other packages.

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54a3d79..51c0463 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+
 ## 2.2.0-nullsafety-dev
 
 Pre-release for the null safety migration of this package.
@@ -9,6 +10,8 @@
 2.10.0-2.0.dev, which is the first version where this package will appear in the
 null safety allow list.
 
+  * AddsSHA-2 512/224 and SHA-2 512/256 from FIPS 180-4
+
 ## 2.1.5
 
 * Improve example and package description to address package site maintenance
diff --git a/README.md b/README.md
index 46ca42e..b65ed09 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,8 @@
 * SHA-256
 * SHA-384
 * SHA-512
+* SHA-512/224
+* SHA-512/256
 * MD5
 * HMAC (i.e. HMAC-MD5, HMAC-SHA1, HMAC-SHA256)
 
diff --git a/lib/src/sha512.dart b/lib/src/sha512.dart
index e32ab2d..39e9595 100644
--- a/lib/src/sha512.dart
+++ b/lib/src/sha512.dart
@@ -10,19 +10,33 @@
 import 'sha512_fastsinks.dart' if (dart.library.js) 'sha512_slowsinks.dart';
 import 'utils.dart';
 
-/// An instance of [Sha2Sha384].
+/// A reusable instance of [Sha384].
 ///
-/// This instance provides convenient access to the [Sha384][rfc] hash function.
+/// This instance provides convenient and canonical access to the
+/// [Sha384][rfc] hash functionality.
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc6234
-final sha384 = Sha384._();
+const sha384 = Sha384._();
 
-/// An instance of [Sha2Sha512].
+/// A reusable instance of [Sha512].
 ///
-/// This instance provides convenient access to the [Sha512][rfc] hash function.
+/// This instance provides convenient and canonical access to the
+/// [Sha512][rfc] hash functionality.
 ///
 /// [rfc]: http://tools.ietf.org/html/rfc6234
-final sha512 = Sha512._();
+const sha512 = Sha512._();
+
+/// A reusable, canonical instance of the [Sha512/224][FIPS] [Hash]
+/// functionality.
+///
+/// [FIPS]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+const sha512224 = _Sha512224();
+
+/// A reusable, canonical instance of the [Sha512/256][FIPS] [Hash]
+/// functionality.
+///
+/// [FIPS]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+const sha512256 = _Sha512256();
 
 /// An implementation of the [SHA-384][rfc] hash function.
 ///
@@ -34,7 +48,7 @@
   @override
   final int blockSize = 32 * bytesPerWord;
 
-  Sha384._();
+  const Sha384._();
 
   Sha384 newInstance() => Sha384._();
 
@@ -49,13 +63,49 @@
 ///
 /// Note that it's almost always easier to use [sha512] rather than creating a
 /// new instance.
-class Sha512 extends Sha384 {
-  Sha512._() : super._();
-
+class Sha512 extends Hash {
   @override
+  final int blockSize = 32 * bytesPerWord;
+
+  const Sha512._();
+
   Sha512 newInstance() => Sha512._();
 
   @override
   ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
       ByteConversionSink.from(Sha512Sink(sink));
 }
+
+/// An implementation of the [SHA-512/224][FIPS] hash function.
+///
+/// [FIPS]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+///
+/// Note that it's almost always easier to use [sha512224] rather than creating
+/// a new instance.
+class _Sha512224 extends Hash {
+  @override
+  final int blockSize = 32 * bytesPerWord;
+
+  const _Sha512224();
+
+  @override
+  ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
+      ByteConversionSink.from(Sha512224Sink(sink));
+}
+
+/// An implementation of the [SHA-512/256][FIPS] hash function.
+///
+/// [FIPS]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
+///
+/// Note that it's almost always easier to use [sha512256] rather than creating
+/// a new instance.
+class _Sha512256 extends Hash {
+  @override
+  final int blockSize = 32 * bytesPerWord;
+
+  const _Sha512256();
+
+  @override
+  ByteConversionSink startChunkedConversion(Sink<Digest> sink) =>
+      ByteConversionSink.from(Sha512256Sink(sink));
+}
diff --git a/lib/src/sha512_fastsinks.dart b/lib/src/sha512_fastsinks.dart
index ea3a449..0e07af6 100644
--- a/lib/src/sha512_fastsinks.dart
+++ b/lib/src/sha512_fastsinks.dart
@@ -144,6 +144,54 @@
             ]));
 }
 
+/// The concrete implementation of [Sha512/224].
+///
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
+class Sha512224Sink extends _Sha64BitSink {
+  @override
+  final digestBytes = 7;
+
+  Sha512224Sink(Sink<Digest> sink)
+      : super(
+            sink,
+            Uint64List.fromList([
+              // FIPS 180-4, Section 5.3.6.1
+              0x8c3d37c819544da2,
+              0x73e1996689dcd4d6,
+              0x1dfab7ae32ff9c82,
+              0x679dd514582f9fcf,
+              0x0f6d2b697bd44da8,
+              0x77e36f7304c48942,
+              0x3f9d85a86a1d36c8,
+              0x1112e6ad91d692a1,
+            ]));
+}
+
+/// The concrete implementation of [Sha512/256].
+///
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
+class Sha512256Sink extends _Sha64BitSink {
+  @override
+  final digestBytes = 8;
+
+  Sha512256Sink(Sink<Digest> sink)
+      : super(
+            sink,
+            Uint64List.fromList([
+              // FIPS 180-4, Section 5.3.6.2
+              0x22312194fc2bf72c,
+              0x9f555fa3c84c64c2,
+              0x2393b86b6f53b151,
+              0x963877195940eabd,
+              0x96283ee2a88effe3,
+              0xbe5e1e2553863992,
+              0x2b0199fc2c85b8aa,
+              0x0eb72ddc81c52ca2,
+            ]));
+}
+
 final _noise64 = Uint64List.fromList([
   0x428a2f98d728ae22,
   0x7137449123ef65cd,
diff --git a/lib/src/sha512_slowsinks.dart b/lib/src/sha512_slowsinks.dart
index 155b240..71225ec 100644
--- a/lib/src/sha512_slowsinks.dart
+++ b/lib/src/sha512_slowsinks.dart
@@ -327,3 +327,51 @@
               0x5be0cd19, 0x137e2179,
             ]));
 }
+
+/// The concrete implementation of [Sha512/224].
+///
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
+class Sha512224Sink extends _Sha64BitSink {
+  @override
+  final digestBytes = 7;
+
+  Sha512224Sink(Sink<Digest> sink)
+      : super(
+            sink,
+            Uint32List.fromList([
+              // FIPS 180-4, Section 5.3.6.1
+              0x8c3d37c8, 0x19544da2,
+              0x73e19966, 0x89dcd4d6,
+              0x1dfab7ae, 0x32ff9c82,
+              0x679dd514, 0x582f9fcf,
+              0x0f6d2b69, 0x7bd44da8,
+              0x77e36f73, 0x04c48942,
+              0x3f9d85a8, 0x6a1d36c8,
+              0x1112e6ad, 0x91d692a1,
+            ]));
+}
+
+/// The concrete implementation of [Sha512/256].
+///
+/// This is separate so that it can extend [HashSink] without leaking additional
+/// public members.
+class Sha512256Sink extends _Sha64BitSink {
+  @override
+  final digestBytes = 8;
+
+  Sha512256Sink(Sink<Digest> sink)
+      : super(
+            sink,
+            Uint32List.fromList([
+              // FIPS 180-4, Section 5.3.6.2
+              0x22312194, 0xfc2bf72c,
+              0x9f555fa3, 0xc84c64c2,
+              0x2393b86b, 0x6f53b151,
+              0x96387719, 0x5940eabd,
+              0x96283ee2, 0xa88effe3,
+              0xbe5e1e25, 0x53863992,
+              0x2b0199fc, 0x2c85b8aa,
+              0x0eb72ddc, 0x81c52ca2,
+            ]));
+}
diff --git a/test/sha_monte_test.dart b/test/sha_monte_test.dart
index a41b0b8..24a319c 100644
--- a/test/sha_monte_test.dart
+++ b/test/sha_monte_test.dart
@@ -5,6 +5,8 @@
 
 import 'utils.dart';
 
+// See https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Secure-Hashing
+
 void main() {
   group('Monte Vectors', () {
     monteTest(
@@ -32,27 +34,55 @@
       ],
     );
     monteTest(
-        'sha384',
-        sha384,
-        'edff07255c71b54a9beae52cdfa083569a08be89949cbba73ddc8acf429359ca5e5be7a673633ca0d9709848f522a9df',
-        [
-          'e81b86c49a38feddfd185f71ca7da6732a053ed4a2640d52d27f53f9f76422650b0e93645301ac99f8295d6f820f1035',
-          '1d6bd21713bffd50946a10c39a7742d740e8f271f0c8f643d4c95375094fd9bf29d89ee61a76053f22e44a4b058a64ed',
-          '425167b66ae965bd7d68515b54ebfa16f33d2bdb2147a4eac515a75224cd19cea564d692017d2a1c41c1a3f68bb5a209',
-          '9e7477ffd4baad1fcca035f4687b35ed47a57832fb27d131eb8018fcb41edf4d5e25874466d2e2d61ae3accdfc7aa364',
-          'd7b4d4e779ca70c8d065630db1f9128ee43b4bde08a81bce13d48659b6ef47b6cfc802af6d8756f6cd43c709bb445bab',
-        ]);
+      'sha384',
+      sha384,
+      'edff07255c71b54a9beae52cdfa083569a08be89949cbba73ddc8acf429359ca5e5be7a673633ca0d9709848f522a9df',
+      [
+        'e81b86c49a38feddfd185f71ca7da6732a053ed4a2640d52d27f53f9f76422650b0e93645301ac99f8295d6f820f1035',
+        '1d6bd21713bffd50946a10c39a7742d740e8f271f0c8f643d4c95375094fd9bf29d89ee61a76053f22e44a4b058a64ed',
+        '425167b66ae965bd7d68515b54ebfa16f33d2bdb2147a4eac515a75224cd19cea564d692017d2a1c41c1a3f68bb5a209',
+        '9e7477ffd4baad1fcca035f4687b35ed47a57832fb27d131eb8018fcb41edf4d5e25874466d2e2d61ae3accdfc7aa364',
+        'd7b4d4e779ca70c8d065630db1f9128ee43b4bde08a81bce13d48659b6ef47b6cfc802af6d8756f6cd43c709bb445bab',
+      ],
+    );
     monteTest(
-        'sha512',
-        sha512,
-        '5c337de5caf35d18ed90b5cddfce001ca1b8ee8602f367e7c24ccca6f893802fb1aca7a3dae32dcd60800a59959bc540d63237876b799229ae71a2526fbc52cd',
-        [
-          'ada69add0071b794463c8806a177326735fa624b68ab7bcab2388b9276c036e4eaaff87333e83c81c0bca0359d4aeebcbcfd314c0630e0c2af68c1fb19cc470e',
-          'ef219b37c24ae507a2b2b26d1add51b31fb5327eb8c3b19b882fe38049433dbeccd63b3d5b99ba2398920bcefb8aca98cd28a1ee5d2aaf139ce58a15d71b06b4',
-          'c3d5087a62db0e5c6f5755c417f69037308cbce0e54519ea5be8171496cc6d18023ba15768153cfd74c7e7dc103227e9eed4b0f82233362b2a7b1a2cbcda9daf',
-          'bb3a58f71148116e377505461d65d6c89906481fedfbcfe481b7aa8ceb977d252b3fe21bfff6e7fbf7575ceecf5936bd635e1cf52698c36ef6908ddbd5b6ae05',
-          'b68f0cd2d63566b3934a50666dec6d62ca1db98e49d7733084c1f86d91a8a08c756fa7ece815e20930dd7cb66351bad8c087c2f94e8757cb98e7f4b86b21a8a8',
-        ]);
+      'sha512',
+      sha512,
+      '5c337de5caf35d18ed90b5cddfce001ca1b8ee8602f367e7c24ccca6f893802fb1aca7a3dae32dcd60800a59959bc540d63237876b799229ae71a2526fbc52cd',
+      [
+        'ada69add0071b794463c8806a177326735fa624b68ab7bcab2388b9276c036e4eaaff87333e83c81c0bca0359d4aeebcbcfd314c0630e0c2af68c1fb19cc470e',
+        'ef219b37c24ae507a2b2b26d1add51b31fb5327eb8c3b19b882fe38049433dbeccd63b3d5b99ba2398920bcefb8aca98cd28a1ee5d2aaf139ce58a15d71b06b4',
+        'c3d5087a62db0e5c6f5755c417f69037308cbce0e54519ea5be8171496cc6d18023ba15768153cfd74c7e7dc103227e9eed4b0f82233362b2a7b1a2cbcda9daf',
+        'bb3a58f71148116e377505461d65d6c89906481fedfbcfe481b7aa8ceb977d252b3fe21bfff6e7fbf7575ceecf5936bd635e1cf52698c36ef6908ddbd5b6ae05',
+        'b68f0cd2d63566b3934a50666dec6d62ca1db98e49d7733084c1f86d91a8a08c756fa7ece815e20930dd7cb66351bad8c087c2f94e8757cb98e7f4b86b21a8a8',
+      ],
+    );
+
+    monteTest(
+      'sha512/224',
+      sha512224,
+      '2e325bf8c98c0be54493d04c329e706343aebe4968fdd33b37da9c0a',
+      [
+        '9ee006873962aa0842d636c759646a4ef4b65bcbebcc35430b20f7f4',
+        '87726eda4570734b396f4c253146ecb9770b8591739240f02a4f2a02',
+        '7be0871653db5fa514b4ec1a0363df004657155575b0383bc9fdec35',
+        '7a794a3a1ae255e67ffbf688a05b6aba7f231cebec64b4fc75092d49',
+        'aaf5d4ecaf9426149821b15821b41c49e3900c0fc91664fb294216ea',
+      ],
+    );
+
+    monteTest(
+      'sha512/256',
+      sha512256,
+      'f41ece2613e4573915696b5adcd51ca328be3bf566a9ca99c9ceb0279c1cb0a7',
+      [
+        'b1d97a6536896aa01098fb2b9e15d8692621c84077051fc1f70a8a48baa6dfaf',
+        'a008d2c5adce31a95b30397ac691d8606c6769a47b801441ba3afb7f727c8a9c',
+        '8eb896cb2b309db019121eb72564b89c1a59f74d4e2f2f6773c87b98c1997d77',
+        'ac71b694438cc300dde0f6f9f548d2304e2bdb6ea45e2b305af5fb3e4ec27761',
+        'd47cca4ae027778fc285bc78fb2a9c1cc7cde498267c35157e86b05fc58e698d',
+      ],
+    );
   });
 }