diff options
Diffstat (limited to 'src/lib/hash/sha3')
-rw-r--r-- | src/lib/hash/sha3/sha3.cpp | 77 | ||||
-rw-r--r-- | src/lib/hash/sha3/sha3.h | 33 |
2 files changed, 76 insertions, 34 deletions
diff --git a/src/lib/hash/sha3/sha3.cpp b/src/lib/hash/sha3/sha3.cpp index 3897f0588..2361d7d5b 100644 --- a/src/lib/hash/sha3/sha3.cpp +++ b/src/lib/hash/sha3/sha3.cpp @@ -109,16 +109,6 @@ SHA_3::SHA_3(size_t output_bits) : std::to_string(output_bits)); } -SHA_3::SHA_3(size_t output_bits, size_t capacity) : - m_output_bits(output_bits), - m_bitrate(1600 - capacity), - m_S(25), - m_S_pos(0) - { - if(capacity == 0 || capacity >= 1600) - throw Invalid_Argument("Impossible SHA-3 capacity specified"); - } - std::string SHA_3::name() const { return "SHA-3(" + std::to_string(m_output_bits) + ")"; @@ -135,49 +125,84 @@ void SHA_3::clear() m_S_pos = 0; } -void SHA_3::add_data(const byte input[], size_t length) +//static +size_t SHA_3::absorb(size_t bitrate, + secure_vector<uint64_t>& S, size_t S_pos, + const byte input[], size_t length) { - if(length == 0) - return; - - while(length) + while(length > 0) { - size_t to_take = std::min(length, m_bitrate / 8 - m_S_pos); + size_t to_take = std::min(length, bitrate / 8 - S_pos); length -= to_take; - while(to_take && m_S_pos % 8) + while(to_take && S_pos % 8) { - m_S[m_S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (m_S_pos % 8)); + S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8)); - ++m_S_pos; + ++S_pos; ++input; --to_take; } while(to_take && to_take % 8 == 0) { - m_S[m_S_pos / 8] ^= load_le<u64bit>(input, 0); - m_S_pos += 8; + S[S_pos / 8] ^= load_le<u64bit>(input, 0); + S_pos += 8; input += 8; to_take -= 8; } while(to_take) { - m_S[m_S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (m_S_pos % 8)); + S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8)); - ++m_S_pos; + ++S_pos; ++input; --to_take; } - if(m_S_pos == m_bitrate / 8) + if(S_pos == bitrate / 8) { - SHA_3::permute(m_S.data()); - m_S_pos = 0; + SHA_3::permute(S.data()); + S_pos = 0; } } + + return S_pos; + } + +//static +void SHA_3::expand(size_t bitrate, + secure_vector<uint64_t>& S, + byte output[], size_t output_length) + { + BOTAN_ARG_CHECK(bitrate % 8 == 0); + + size_t Si = 0; + + for(size_t i = 0; i != output_length; ++i) + { + if(i > 0) + { + if(i % (bitrate / 8) == 0) + { + SHA_3::permute(S.data()); + Si = 0; + } + else if(i % 8 == 0) + { + Si += 1; + } + } + + output[i] = get_byte(7 - (i % 8), S[Si]); + } + } + +void SHA_3::add_data(const byte input[], size_t length) + { + m_S_pos = SHA_3::absorb(m_bitrate, m_S, m_S_pos, input, length); } void SHA_3::final_result(byte output[]) diff --git a/src/lib/hash/sha3/sha3.h b/src/lib/hash/sha3/sha3.h index c877bd938..649aa12fd 100644 --- a/src/lib/hash/sha3/sha3.h +++ b/src/lib/hash/sha3/sha3.h @@ -27,14 +27,6 @@ class BOTAN_DLL SHA_3 : public HashFunction */ SHA_3(size_t output_bits); - /** - * @param output_bits the size of the hash output; must be a - * multiple of 8 (ie, byte-wide outputs) - * @param capacity the capacity of the spong, normally always - * 2*output_bits with SHA-3. - */ - SHA_3(size_t output_bits, size_t capacity); - size_t hash_block_size() const override { return m_bitrate / 8; } size_t output_length() const override { return m_output_bits / 8; } @@ -42,6 +34,31 @@ class BOTAN_DLL SHA_3 : public HashFunction std::string name() const override; void clear() override; + // Static functions for internal usage + + /** + * Absorb data into the provided state + * @param bitrate the bitrate to absorb into the sponge + * @param S the sponge state + * @param S_pos where to begin absorbing into S + * @param input the input data + * @param length size of input in bytes + */ + static size_t absorb(size_t bitrate, + secure_vector<uint64_t>& S, size_t S_pos, + const byte input[], size_t length); + + /** + * Expand from provided state + * @param bitrate sponge parameter + * @param S the state + * @param output the output buffer + * @param output_length the size of output in bytes + */ + static void expand(size_t bitrate, + secure_vector<uint64_t>& S, + byte output[], size_t output_length); + /** * The bare Keccak-1600 permutation */ |