aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/stream/shake_cipher/shake_cipher.cpp34
-rw-r--r--src/lib/stream/stream_cipher.cpp2
-rw-r--r--src/tests/data/stream/shake128.vec56
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