summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp')
-rw-r--r--comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp b/comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp
new file mode 100644
index 0000000000..f1920959e3
--- /dev/null
+++ b/comm/third_party/botan/src/lib/stream/shake_cipher/shake_cipher.cpp
@@ -0,0 +1,90 @@
+/*
+* SHAKE-128
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/shake_cipher.h>
+#include <botan/exceptn.h>
+#include <botan/sha3.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+SHAKE_128_Cipher::SHAKE_128_Cipher() :
+ m_buf_pos(0)
+ {}
+
+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 >= SHAKE_128_BYTERATE - 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(), SHAKE_128_BYTERATE, m_state.data());
+
+ m_buf_pos = 0;
+ }
+ xor_buf(out, in, &m_buffer[m_buf_pos], length);
+ m_buf_pos += 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(SHAKE_128_BITRATE/8);
+ zeroise(m_state);
+
+ 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());
+ }
+
+void SHAKE_128_Cipher::clear()
+ {
+ zap(m_state);
+ zap(m_buffer);
+ m_buf_pos = 0;
+ }
+
+void SHAKE_128_Cipher::set_iv(const uint8_t[], size_t length)
+ {
+ /*
+ * This could be supported in some way (say, by treating iv as
+ * a prefix or suffix of the key).
+ */
+ if(length != 0)
+ throw Invalid_IV_Length(name(), length);
+ }
+
+void SHAKE_128_Cipher::seek(uint64_t)
+ {
+ throw Not_Implemented("SHAKE_128_Cipher::seek");
+ }
+
+Key_Length_Specification SHAKE_128_Cipher::key_spec() const
+ {
+ return Key_Length_Specification(1, 160);
+ }
+
+std::string SHAKE_128_Cipher::name() const
+ {
+ return "SHAKE-128";
+ }
+
+StreamCipher* SHAKE_128_Cipher::clone() const
+ {
+ return new SHAKE_128_Cipher;
+ }
+
+}