Skip to content

Commit

Permalink
Clean up the Keccak_Permutation
Browse files Browse the repository at this point in the history
* replace single-shot ::expand() with more versatile ::squeeze()
* use BufferStuffer/BufferSlicer in ::squeeze() and ::absorb()
* remove low-level access to Keccak state
* remove static Keccak state mutation methods
* ::permute() is now private
  • Loading branch information
reneme committed Aug 19, 2023
1 parent faeca4a commit 88c4a1c
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 292 deletions.
7 changes: 3 additions & 4 deletions src/lib/hash/keccak/keccak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ std::unique_ptr<HashFunction> Keccak_1600::copy_state() const {
return std::make_unique<Keccak_1600>(*this);
}

Keccak_1600::Keccak_1600(size_t output_bits) : m_keccak(2 * output_bits, 0, 0), m_output_length(output_bits/8) {
Keccak_1600::Keccak_1600(size_t output_bits) : m_keccak(2 * output_bits, 0, 0), m_output_length(output_bits / 8) {
// We only support the parameters for the SHA-3 proposal


if(output_bits != 224 && output_bits != 256 && output_bits != 384 && output_bits != 512) {
throw Invalid_Argument(fmt("Keccak_1600: Invalid output length {}", output_bits));
}
Expand All @@ -40,12 +39,12 @@ void Keccak_1600::clear() {
}

void Keccak_1600::add_data(const uint8_t input[], size_t length) {
m_keccak.absorb(std::span(input, length));
m_keccak.absorb({input, length});
}

void Keccak_1600::final_result(uint8_t output[]) {
m_keccak.finish();
m_keccak.expand(std::span(output, m_output_length));
m_keccak.squeeze({output, m_output_length});
m_keccak.clear();
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/hash/sha3/sha3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Botan {

SHA_3::SHA_3(size_t output_bits) : m_keccak(2 * output_bits, 2, 2), m_output_length(output_bits/8) {
SHA_3::SHA_3(size_t output_bits) : m_keccak(2 * output_bits, 2, 2), m_output_length(output_bits / 8) {
// We only support the parameters for SHA-3 in this constructor

if(output_bits != 224 && output_bits != 256 && output_bits != 384 && output_bits != 512) {
Expand Down Expand Up @@ -44,12 +44,12 @@ void SHA_3::clear() {
}

void SHA_3::add_data(const uint8_t input[], size_t length) {
m_keccak.absorb(std::span(input, length));
m_keccak.absorb({input, length});
}

void SHA_3::final_result(uint8_t output[]) {
m_keccak.finish();
m_keccak.expand(std::span(output, m_output_length));
m_keccak.squeeze({output, m_output_length});
m_keccak.clear();
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/hash/sha3/sha3.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class SHA_3 : public HashFunction {
*/
explicit SHA_3(size_t output_bits);

size_t hash_block_size() const override { return m_keccak.hash_block_size(); }
size_t hash_block_size() const override { return m_keccak.byte_rate(); }

size_t output_length() const override { return m_output_length; }

Expand Down
28 changes: 8 additions & 20 deletions src/lib/hash/shake/shake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@

#include <botan/exceptn.h>
#include <botan/internal/fmt.h>
#include <botan/internal/sha3.h>

namespace Botan {

SHAKE_128::SHAKE_128(size_t output_bits) : m_output_bits(output_bits), m_S(25), m_S_pos(0) {
SHAKE_128::SHAKE_128(size_t output_bits) : m_keccak(256, 0xF, 4), m_output_bits(output_bits) {
if(output_bits % 8 != 0) {
throw Invalid_Argument(fmt("SHAKE_128: Invalid output length {}", output_bits));
}
Expand All @@ -31,22 +30,17 @@ std::unique_ptr<HashFunction> SHAKE_128::copy_state() const {
return std::make_unique<SHAKE_128>(*this);
}

void SHAKE_128::clear() {
zeroise(m_S);
m_S_pos = 0;
}

void SHAKE_128::add_data(const uint8_t input[], size_t length) {
m_S_pos = Keccak_Permutation::absorb(SHAKE_128_BITRATE, m_S, m_S_pos, std::span(input, length));
m_keccak.absorb({input, length});
}

void SHAKE_128::final_result(uint8_t output[]) {
Keccak_Permutation::finish(SHAKE_128_BITRATE, m_S, m_S_pos, 0xF, 4);
Keccak_Permutation::expand(SHAKE_128_BITRATE, m_S, std::span(output, output_length()));
m_keccak.finish();
m_keccak.squeeze({output, output_length()});
clear();
}

SHAKE_256::SHAKE_256(size_t output_bits) : m_output_bits(output_bits), m_S(25), m_S_pos(0) {
SHAKE_256::SHAKE_256(size_t output_bits) : m_keccak(512, 0xF, 4), m_output_bits(output_bits) {
if(output_bits % 8 != 0) {
throw Invalid_Argument(fmt("SHAKE_256: Invalid output length {}", output_bits));
}
Expand All @@ -64,19 +58,13 @@ std::unique_ptr<HashFunction> SHAKE_256::copy_state() const {
return std::make_unique<SHAKE_256>(*this);
}

void SHAKE_256::clear() {
zeroise(m_S);
m_S_pos = 0;
}

void SHAKE_256::add_data(const uint8_t input[], size_t length) {
m_S_pos = Keccak_Permutation::absorb(SHAKE_256_BITRATE, m_S, m_S_pos, std::span(input, length));
m_keccak.absorb({input, length});
}

void SHAKE_256::final_result(uint8_t output[]) {
Keccak_Permutation::finish(SHAKE_256_BITRATE, m_S, m_S_pos, 0xF, 4);
Keccak_Permutation::expand(SHAKE_256_BITRATE, m_S, std::span(output, output_length()));

m_keccak.finish();
m_keccak.squeeze({output, output_length()});
clear();
}

Expand Down
23 changes: 10 additions & 13 deletions src/lib/hash/shake/shake.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#define BOTAN_SHAKE_HASH_H_

#include <botan/hash.h>
#include <botan/secmem.h>
#include <botan/internal/keccak_perm.h>

#include <string>

namespace Botan {
Expand All @@ -25,24 +26,22 @@ class SHAKE_128 final : public HashFunction {
*/
explicit SHAKE_128(size_t output_bits);

size_t hash_block_size() const override { return SHAKE_128_BITRATE / 8; }
size_t hash_block_size() const override { return m_keccak.byte_rate(); }

size_t output_length() const override { return m_output_bits / 8; }

std::unique_ptr<HashFunction> new_object() const override;
std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;

void clear() override { m_keccak.clear(); }

private:
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;

static const size_t SHAKE_128_BITRATE = 1600 - 256;

Keccak_Permutation m_keccak;
size_t m_output_bits;
secure_vector<uint64_t> m_S;
size_t m_S_pos;
};

/**
Expand All @@ -56,24 +55,22 @@ class SHAKE_256 final : public HashFunction {
*/
explicit SHAKE_256(size_t output_bits);

size_t hash_block_size() const override { return SHAKE_256_BITRATE / 8; }
size_t hash_block_size() const override { return m_keccak.byte_rate(); }

size_t output_length() const override { return m_output_bits / 8; }

std::unique_ptr<HashFunction> new_object() const override;
std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;

void clear() override { m_keccak.clear(); }

private:
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;

static const size_t SHAKE_256_BITRATE = 1600 - 512;

Keccak_Permutation m_keccak;
size_t m_output_bits;
secure_vector<uint64_t> m_S;
size_t m_S_pos;
};

} // namespace Botan
Expand Down
Loading

0 comments on commit 88c4a1c

Please sign in to comment.