diff --git a/CHANGELOG.md b/CHANGELOG.md index 54a3d79f80e84..51c04638cff68 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 @@ This release will be pinned to only allow pre-release sdk versions starting from 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 46ca42ee5eab9..b65ed09c6841e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ The following hashing algorithms are supported: * 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 e32ab2d5e5c7f..39e959533b6ca 100644 --- a/lib/src/sha512.dart +++ b/lib/src/sha512.dart @@ -10,19 +10,33 @@ import 'hash.dart'; 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 @@ class Sha384 extends Hash { @override final int blockSize = 32 * bytesPerWord; - Sha384._(); + const Sha384._(); Sha384 newInstance() => Sha384._(); @@ -49,13 +63,49 @@ class Sha384 extends Hash { /// /// 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 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 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 sink) => + ByteConversionSink.from(Sha512256Sink(sink)); +} diff --git a/lib/src/sha512_fastsinks.dart b/lib/src/sha512_fastsinks.dart index ea3a449622e07..0e07af6d171bb 100644 --- a/lib/src/sha512_fastsinks.dart +++ b/lib/src/sha512_fastsinks.dart @@ -144,6 +144,54 @@ class Sha512Sink extends _Sha64BitSink { ])); } +/// 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 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 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 155b240b10ec8..71225ec62b28f 100644 --- a/lib/src/sha512_slowsinks.dart +++ b/lib/src/sha512_slowsinks.dart @@ -327,3 +327,51 @@ class Sha512Sink extends _Sha64BitSink { 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 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 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 a41b0b8a64207..24a319c1a0247 100644 --- a/test/sha_monte_test.dart +++ b/test/sha_monte_test.dart @@ -5,6 +5,8 @@ import 'package:crypto/crypto.dart'; 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 @@ void main() { ], ); 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', + ], + ); + monteTest( - 'sha512', - sha512, - '5c337de5caf35d18ed90b5cddfce001ca1b8ee8602f367e7c24ccca6f893802fb1aca7a3dae32dcd60800a59959bc540d63237876b799229ae71a2526fbc52cd', - [ - 'ada69add0071b794463c8806a177326735fa624b68ab7bcab2388b9276c036e4eaaff87333e83c81c0bca0359d4aeebcbcfd314c0630e0c2af68c1fb19cc470e', - 'ef219b37c24ae507a2b2b26d1add51b31fb5327eb8c3b19b882fe38049433dbeccd63b3d5b99ba2398920bcefb8aca98cd28a1ee5d2aaf139ce58a15d71b06b4', - 'c3d5087a62db0e5c6f5755c417f69037308cbce0e54519ea5be8171496cc6d18023ba15768153cfd74c7e7dc103227e9eed4b0f82233362b2a7b1a2cbcda9daf', - 'bb3a58f71148116e377505461d65d6c89906481fedfbcfe481b7aa8ceb977d252b3fe21bfff6e7fbf7575ceecf5936bd635e1cf52698c36ef6908ddbd5b6ae05', - 'b68f0cd2d63566b3934a50666dec6d62ca1db98e49d7733084c1f86d91a8a08c756fa7ece815e20930dd7cb66351bad8c087c2f94e8757cb98e7f4b86b21a8a8', - ]); + 'sha512/224', + sha512224, + '2e325bf8c98c0be54493d04c329e706343aebe4968fdd33b37da9c0a', + [ + '9ee006873962aa0842d636c759646a4ef4b65bcbebcc35430b20f7f4', + '87726eda4570734b396f4c253146ecb9770b8591739240f02a4f2a02', + '7be0871653db5fa514b4ec1a0363df004657155575b0383bc9fdec35', + '7a794a3a1ae255e67ffbf688a05b6aba7f231cebec64b4fc75092d49', + 'aaf5d4ecaf9426149821b15821b41c49e3900c0fc91664fb294216ea', + ], + ); + + monteTest( + 'sha512/256', + sha512256, + 'f41ece2613e4573915696b5adcd51ca328be3bf566a9ca99c9ceb0279c1cb0a7', + [ + 'b1d97a6536896aa01098fb2b9e15d8692621c84077051fc1f70a8a48baa6dfaf', + 'a008d2c5adce31a95b30397ac691d8606c6769a47b801441ba3afb7f727c8a9c', + '8eb896cb2b309db019121eb72564b89c1a59f74d4e2f2f6773c87b98c1997d77', + 'ac71b694438cc300dde0f6f9f548d2304e2bdb6ea45e2b305af5fb3e4ec27761', + 'd47cca4ae027778fc285bc78fb2a9c1cc7cde498267c35157e86b05fc58e698d', + ], + ); }); }