diff options
-rw-r--r-- | src/lib/stream/shake_cipher/shake_cipher.cpp | 34 | ||||
-rw-r--r-- | src/lib/stream/stream_cipher.cpp | 2 | ||||
-rw-r--r-- | src/tests/data/stream/shake128.vec | 56 |
3 files changed, 70 insertions, 22 deletions
diff --git a/src/lib/stream/shake_cipher/shake_cipher.cpp b/src/lib/stream/shake_cipher/shake_cipher.cpp index b0e08a700..f1920959e 100644 --- a/src/lib/stream/shake_cipher/shake_cipher.cpp +++ b/src/lib/stream/shake_cipher/shake_cipher.cpp @@ -18,17 +18,19 @@ SHAKE_128_Cipher::SHAKE_128_Cipher() : void SHAKE_128_Cipher::cipher(const uint8_t in[], uint8_t out[], size_t length) { + const size_t SHAKE_128_BYTERATE = (1600-256)/8; + verify_key_set(m_state.empty() == false); - while(length >= m_buffer.size() - m_buf_pos) + while(length >= SHAKE_128_BYTERATE - m_buf_pos) { - xor_buf(out, in, &m_buffer[m_buf_pos], m_buffer.size() - m_buf_pos); - length -= (m_buffer.size() - m_buf_pos); - in += (m_buffer.size() - m_buf_pos); - out += (m_buffer.size() - m_buf_pos); + xor_buf(out, in, &m_buffer[m_buf_pos], SHAKE_128_BYTERATE - m_buf_pos); + length -= (SHAKE_128_BYTERATE - m_buf_pos); + in += (SHAKE_128_BYTERATE - m_buf_pos); + out += (SHAKE_128_BYTERATE - m_buf_pos); SHA_3::permute(m_state.data()); - copy_out_le(m_buffer.data(), m_buffer.size(), m_state.data()); + copy_out_le(m_buffer.data(), SHAKE_128_BYTERATE, m_state.data()); m_buf_pos = 0; } @@ -38,19 +40,13 @@ void SHAKE_128_Cipher::cipher(const uint8_t in[], uint8_t out[], size_t length) void SHAKE_128_Cipher::key_schedule(const uint8_t key[], size_t length) { + const size_t SHAKE_128_BITRATE = (1600-256); m_state.resize(25); - m_buffer.resize((1600 - 256) / 8); + m_buffer.resize(SHAKE_128_BITRATE/8); zeroise(m_state); - for(size_t i = 0; i < length/8; ++i) - { - m_state[i] ^= load_le<uint64_t>(key, i); - } - - m_state[length/8] ^= 0x000000000000001F; - m_state[20] ^= 0x8000000000000000; - - SHA_3::permute(m_state.data()); + const size_t S_pos = SHA_3::absorb(SHAKE_128_BITRATE, m_state, 0, key, length); + SHA_3::finish(SHAKE_128_BITRATE, m_state, S_pos, 0x1F, 0x80); copy_out_le(m_buffer.data(), m_buffer.size(), m_state.data()); } @@ -78,11 +74,7 @@ void SHAKE_128_Cipher::seek(uint64_t) Key_Length_Specification SHAKE_128_Cipher::key_spec() const { - /* - In principle SHAKE can accept arbitrary length inputs, but this - does not seem required for a stream cipher. - */ - return Key_Length_Specification(16, 160, 8); + return Key_Length_Specification(1, 160); } std::string SHAKE_128_Cipher::name() const diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp index 692464723..340682ce2 100644 --- a/src/lib/stream/stream_cipher.cpp +++ b/src/lib/stream/stream_cipher.cpp @@ -82,7 +82,7 @@ std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec, #endif #if defined(BOTAN_HAS_SHAKE_CIPHER) - if(req.algo_name() == "SHAKE-128") + if(req.algo_name() == "SHAKE-128" || req.algo_name() == "SHAKE-128-XOF") { if(provider.empty() || provider == "base") return std::unique_ptr<StreamCipher>(new SHAKE_128_Cipher); diff --git a/src/tests/data/stream/shake128.vec b/src/tests/data/stream/shake128.vec index b2740405c..02ebfbcf2 100644 --- a/src/tests/data/stream/shake128.vec +++ b/src/tests/data/stream/shake128.vec @@ -3377,3 +3377,59 @@ Out = 0db7f7196eee8dd6994a16ded19cb09f05f89ccd2464333df2c017c6ca041fa0d54a4832a7 Key = 0a13ad2c7a239b4ba73ea6592ae84ea9 Out = 5feaf99c15f48851943ff9baa6e5055d8377f0dd347aa4dbece51ad3a6d9ce0c01aee9fe2260b80a4673a909b532adcdd1e421c32d6460535b5fe392a58d2634979a5a104d6c470aa3306c400b061db91c463b2848297bca2bc26d1864ba49d7ff949ebca50fbf79a5e63716dc82b600bd52ca7437ed774d169f6bf02e46487956fba2230f34cd2a0485484d +Key = 0e +Out = fa996dafaa208d72287c23bc4ed4bfd5 + +Key = d9e8 +Out = c7211512340734235bb8d3c4651495aa + +Key = 1b3b6e +Out = d7335497e4cd3666885edbb0824d7a75 + +Key = 983f235a +Out = a5597fff9277088ab56d4d5485023fec + +Key = 76fc16763f +Out = a539f540f3e69e2d25a46ef0b1cf16dd + +Key = cb1b0103501c +Out = a07d5bd636c2ecca4b239124ef9fcac0 + +Key = 7216a825029da1 +Out = 9de6ffacf3e59693a3de81b02f7db77a + +Key = 7bf2fef375bcaff3 +Out = 5ef5578b89c50532131b7843de7329a3 + +Key = fc948f094aa4b4e035 +Out = 9dfe4efaa2c43081702cbfe8636859ce + +Key = f83091fff290c4b333fb +Out = 637e1cb6bdbebb4793447e81e2a2bb60 + +Key = ae7cafada3e3e9f4314fa2 +Out = ae03aecba2995b344aa8e874808b5b7e + +Key = 84f6cb3dc77b9bf856caf54e +Out = 56538d52b26f967bb9405e0f54fdf6e2 + +Key = 2af26c79175fcca8e13fb783b1 +Out = 9cca3ec830b2d9ef819b377a96a6c94e + +Key = 52977e532bccdb89dfeff7e9e4ad +Out = fbfba5c1e179df1469fcc8588ae5d2cc + +Key = e49706130f266af2946e496e0e722a +Out = 4d84336572ccaabb827e81a0d887ec9a + +Key = d4d67b00ca51397791b81205d5582c0a +Out = d0acfb2a14928caf8c168ae514925e4e + +Key = 6159096096f4cba469db393377c57d9be0 +Out = 281b6b007cb17235b8aab33781c4cf59 + +Key = 43bdb11eac71031f02a11c15a1885fa42898 +Out = de68027da130663a73980e3525b88c75 + +Key = 1e5dff69ea217bdd182fc8d6d25b74792db36d +Out = e1905b84d9c060db55cc119f328695d9 |