diff options
author | SimCog <[email protected]> | 2016-06-14 18:21:10 +0200 |
---|---|---|
committer | SimCog <[email protected]> | 2016-06-18 01:06:21 +0200 |
commit | 00337c4ea2af6b1727be0bdf9b719c98760a14fd (patch) | |
tree | adc8b6f68311b2c9649bdb84766f22f99d2424db /src/lib/stream/chacha/chacha.cpp | |
parent | 6816c9e71e01432792a997ad9a5d561b9cd94a48 (diff) |
Adding StreamCipher::seek interface, supporting seek in ChaCha, and also adding ChaCha8 support
Diffstat (limited to 'src/lib/stream/chacha/chacha.cpp')
-rw-r--r-- | src/lib/stream/chacha/chacha.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp index ac81fd70d..40da93029 100644 --- a/src/lib/stream/chacha/chacha.cpp +++ b/src/lib/stream/chacha/chacha.cpp @@ -12,8 +12,8 @@ namespace Botan { ChaCha::ChaCha(size_t rounds) : m_rounds(rounds) { - if(m_rounds != 12 && m_rounds != 20) - throw Invalid_Argument("ChaCha only supports 12 or 20 rounds"); + if(m_rounds != 8 && m_rounds != 12 && m_rounds != 20) + throw Invalid_Argument("ChaCha only supports 8, 12 or 20 rounds"); } namespace { @@ -67,7 +67,6 @@ void chacha(byte output[64], const u32bit input[16], size_t rounds) store_le(x14 + input[14], output + 4 * 14); store_le(x15 + input[15], output + 4 * 15); } - } /* @@ -173,4 +172,27 @@ std::string ChaCha::name() const return "ChaCha(" + std::to_string(m_rounds) + ")"; } +void ChaCha::seek(u64bit offset) + { + if (m_state.size() == 0 && m_buffer.size() == 0) + { + throw Invalid_State("You have to setup the stream cipher (key and iv)"); + } + + m_position = offset % m_buffer.size(); + + u64bit counter = offset / m_buffer.size(); + + byte out[8]; + + store_le(counter, out); + + m_state[12] = load_le<u32bit>(out, 0); + m_state[13] += load_le<u32bit>(out, 1); + + chacha(m_buffer.data(), m_state.data(), m_rounds); + + ++m_state[12]; + m_state[13] += (m_state[12] == 0); + } } |