diff --git a/hash/blake.cpp b/hash/blake.cpp index 14d395e..9586c72 100644 --- a/hash/blake.cpp +++ b/hash/blake.cpp @@ -218,6 +218,22 @@ compress ( /////////////////////////////////////////////////////////////////////////////// template typename blake::digest_t +blake::operator() ( + util::view data, + util::view salt +) const { + std::array::word_t, 4> fwd {}; + + if (salt.size () > sizeof (fwd)) + throw std::invalid_argument ("oversized salt"); + + memcpy (&fwd, salt.begin (), salt.size ()); + return (*this) (data, fwd); +} + +//----------------------------------------------------------------------------- +template +typename blake::digest_t blake::operator() ( util::view data, const std::array::word_t, 4> salt @@ -243,7 +259,9 @@ blake::operator() ( (unsigned)(last - cursor) >= sizeof (dw); cursor += sizeof (dw)) { - t+= BLOCK_SIZE; + // use the number of bits as the size + t+= block_size * 8; + memcpy (d08, cursor, sizeof (d08)); std::transform ( std::cbegin (dw), diff --git a/hash/blake.hpp b/hash/blake.hpp index 19ad9fd..cc24b66 100644 --- a/hash/blake.hpp +++ b/hash/blake.hpp @@ -46,6 +46,14 @@ namespace cruft::crypto::hash { }; + //------------------------------------------------------------------------- + template <> + struct traits<224> + { + using word_t = traits<256>::word_t; + }; + + //------------------------------------------------------------------------- template <> struct traits<512> @@ -58,13 +66,38 @@ namespace cruft::crypto::hash { static constexpr int rounds = 16; }; + + //------------------------------------------------------------------------- + template <> + struct traits<384> + { + using word_t = traits<512>::word_t; + }; + + + /// an implementation of the BLAKE hash function + /// + /// note that this is _not_ BLAKE2, but the original SHA-3 candidate + /// function. + /// + /// \tparam width the number of bits for the digest template class blake { public: using word_t = typename traits::word_t; - using digest_t = std::array; - static const size_t BLOCK_SIZE = 512; - static const size_t DIGEST_SIZE = sizeof (digest_t); + + // size of each round's data block in bytes + static const size_t block_size = 16 * sizeof (word_t); + + // size of the digest in bytes + static const size_t digest_size = width / 8; + using digest_t = std::array; + + + digest_t operator() ( + util::view data, + util::view salt + ) const; digest_t operator() (util::view data, const std::array salt) const noexcept; diff --git a/test/hash/blake.cpp b/test/hash/blake.cpp index 0f2dead..0cf5579 100644 --- a/test/hash/blake.cpp +++ b/test/hash/blake.cpp @@ -7,72 +7,147 @@ using cruft::crypto::hash::blake; -/////////////////////////////////////////////////////////////////////////////// -static blake<256>::digest_t -operator"" _digest (const char *str, size_t len) -{ - blake<256>::digest_t res; - for (size_t i = 0; i < len; i += 2) - res[i/2] = util::ascii::from_hex (str[i]) << 4 | util::ascii::from_hex (str[i+1]); - - return res; -} - - -//----------------------------------------------------------------------------- -std::vector -operator"" _u8s (const char *str, size_t len) -{ - std::vector res; - res.resize (len); - std::copy_n (str, len, std::begin (res)); - return res; -} - - /////////////////////////////////////////////////////////////////////////////// static const struct { std::vector data; - std::vector salt; - blake<256>::digest_t digest; + std::vector salt; + blake<224>::digest_t d224; + blake<256>::digest_t d256; + blake<384>::digest_t d384; + blake<512>::digest_t d512; const char *message; } TESTS[] = { { {}, {}, + "7dc5313b1c04512a174bd6503b89607a" + "ecbee0903d40a8a569c94eed"_hex2array, "716f6e863f744b9ac22c97ec7b76ea5f" - "5908bc5b2f67c61510bfc4751384ea7a"_digest, + "5908bc5b2f67c61510bfc4751384ea7a"_hex2array, + "c6cbd89c926ab525c242e6621f2f5fa7" + "3aa4afe3d9e24aed727faaadd6af38b6" + "20bdb623dd2b4788b1c8086984af8706"_hex2array, + "a8cfbbd73726062df0c6864dda65defe" + "58ef0cc52a5625090fa17601e1eecd1b" + "628e94f396ae402a00acc9eab77b4d4c" + "2e852aaaa25a636d80af3fc7913ef5b8"_hex2array, + //"716f6e863f744b9ac22c97ec7b76ea5f" + //"5908bc5b2f67c61510bfc4751384ea7a"_hex2array, "empty, default salt" - }, { + }, + { { 0x00 }, { }, - "0ce8d4ef4dd7cd8d62dfded9d4edb0a774ae6a41929a74da23109e8f11139c87"_digest, + "4504cb0314fb2a4f7a692e696e487912" + "fe3f2468fe312c73a5278ec5"_hex2array, + "0ce8d4ef4dd7cd8d62dfded9d4edb0a7" + "74ae6a41929a74da23109e8f11139c87"_hex2array, + "10281f67e135e90ae8e882251a355510" + "a719367ad70227b137343e1bc122015c" + "29391e8545b5272d13a7c2879da3d807"_hex2array, + "97961587f6d970faba6d2478045de6d1" + "fabd09b61ae50932054d52bc29d31be4" + "ff9102b9f69e2bbdb83be13d4b9c0609" + "1e5fa0b48bd081b634058be0ec49beb3"_hex2array, + //"0ce8d4ef4dd7cd8d62dfded9d4edb0a7" + //"74ae6a41929a74da23109e8f11139c87"_hex2array, "NIST 8 bit zeros, default salt", - }, { - "0123456789abcdef"_u8s, + }, + { + "000102030405060708090a0b0c0d0e0f"_hex2u8, {}, - "9dc03986e7cc2973fd21f0c0c804922ef160313d3b4e52c187a1661c5e89877c"_digest, + "41729acd98684538f559a789035bd893" + "b644f38942a8b5614da5a8a6"_hex2array, + "0f899aa730b1b1c5fa8ff2a5013a6f5f" + "cbe5fdac46f18e2a9a9ecb9a99160219"_hex2array, + "b718141c2ca282eb2b91e021444d5bab" + "dc812d13af25d210c0e10423d10e6024" + "5b113161ae0b7d80a60be1794c09a925"_hex2array, + "47bc13549402bb583227ec8c4c408136" + "ab4ecc5dbb11a98a2e755388c8ca11a7" + "521d1d375cf3afe5d958013c9c505493" + "2c3b0fc76a8ff7a1dead2c0b46bdd1f0"_hex2array, + //"0f899aa730b1b1c5fa8ff2a5013a6f5f" + //"cbe5fdac46f18e2a9a9ecb9a99160219"_hex2array, "16 bytes, default salt" - }, { + }, + { - "0123456789abcdef0123456789abcdef0123456789abcdef0123456"_u8s, + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b"_hex2u8, {}, - "f58834fc24e109248d33194551a28852cd3d2d6ed4aba9ab3562bb5a97ce76e1"_digest, + "483d8043171efeb3a6d52e7387f2e90b" + "c81ebeeb647412aa8837b063"_hex2array, + "755f9ce025a066492e2b29c47462c985" + "4ede6874f43467e7fb548172335b4d50"_hex2array, + "28eed2bb102cd19344c9857b29c8adf3" + "11eeaaed0334bc66809bbf0a515171a3" + "cc5a13373a47f16f975290691afb6ec1"_hex2array, + "0a47642c0b54f52cb780a2f425c6e81b" + "4d3d26d60b3ba6e7c7d2f164e28041e2" + "83c4366fd94644d2a6ba5dd7ddb33b70" + "979bbdf6169436840d34a0f18ad7debc"_hex2array, + //"755f9ce025a066492e2b29c47462c985" + //"4ede6874f43467e7fb548172335b4d50"_hex2array, "exactly pre-padding size, default salt" - }, { + }, + { std::vector (576/8, 0), {}, - "d419bad32d504fb7d44d460c42c5593fe544fa4c135dec31e21bd9abdcc22d41"_digest, + "f5aa00dd1cb847e3140372af7b5c46b4" + "888d82c8c0a917913cfb5d04"_hex2array, + "d419bad32d504fb7d44d460c42c5593f" + "e544fa4c135dec31e21bd9abdcc22d41"_hex2array, + "e37d96e5ca54058c348e8c67cac1f93a" + "a13fc64aa4bca19015a582e6505dcbc7" + "d39d661b464d485fb74c75485b30c6c2"_hex2array, + "2f31e729e269c7f22cac8b71cb80a504" + "afe38350498e0d178afb38cc356dfdaf" + "55d1e7d723c8ff686df0710c43d9abef" + "9f0f61b91ab3b49f72b96f899159a735"_hex2array, + //"d419bad32d504fb7d44d460c42c5593f" + //"e544fa4c135dec31e21bd9abdcc22d41"_hex2array, "NIST 576 bit zeros, default salt", - }, { - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde"_u8s, + }, + { + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e"_hex2u8, { }, - "c455dcfcf5c77950b92ff055e7e4f8139acac4cbd18dbed0b1383d95e4f1726c"_digest, + "0a5e8da4f27db9afe24c29a3c6f92ec8" + "831113f144c59a64c37a2016"_hex2array, + "cfce445066d35322557b432540bd2f0a" + "f4caf9f426568236d9944426a5df792a"_hex2array, + "4688779d44b6d0ee1be74fce5a3bf8c0" + "2069c816f01e68e541bd5e6772d6dade" + "b79b6c3193a1c2732206885f29391030"_hex2array, + "d8e947b518ad5700e94a32ebb2f4e5e7" + "34a907637dd24f26ba675cd5f984bdda" + "ce7392993576ff2ab387c19b3fbb920e" + "7f0c1368f910756306070aea6affe1e7"_hex2array, + //"cfce445066d35322557b432540bd2f0a" + //"f4caf9f426568236d9944426a5df792a"_hex2array, "almost block size, default salt" - }, { - "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"_u8s, + }, + { + "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f"_hex2u8, { }, - "e25d021064a61d7af53cefaa0819bb6a351db1d760ed1f85fee671bc18ab7886"_digest, + "08b6960d0b0d6f864c9c2a2331341dd0" + "1745cfbfad200888cdb4b5b7"_hex2array, + "4432b2c1e983b0c326583516920f3949" + "c2acf5d85a99353601228cab40c867bc"_hex2array, + "917d92609d640f06cba773be8604d177" + "492649c39a4ce85df643c0b72293053f" + "f39967691cbb1809737eaf6734e1b185"_hex2array, + "4d47291b807750d2ce6ced17ae71dc24" + "f5a3205f4fe309537488242c4420cd32" + "d997beda4d560200cbcf3e9d68143e69" + "f08c54b82ce77db7c22d0e17b5a1363e"_hex2array, + //"4432b2c1e983b0c326583516920f3949c2acf5d85a99353601228cab40c867bc"_hex2array, "exactly block size, default salt", }, }; @@ -90,8 +165,7 @@ main () for (const auto &t: TESTS) { blake<256> h256; - const auto d = h256 (t.data, t.salt); - tap.expect_eq (d, t.digest, "%s", t.message); + tap.expect_eq (h256 (t.data, t.salt), t.d256, "%s", t.message); } { @@ -99,7 +173,7 @@ main () std::vector data (1'000'000, 'a'); tap.expect_eq ( h256 (data), - "22be6de4aa4214c9403f10598f0a6b0e834570251a13bc27589437f7139a5d44"_digest, + "22be6de4aa4214c9403f10598f0a6b0e834570251a13bc27589437f7139a5d44"_hex2array, "million 'a', 256" ); }