45 AbstractKeccakImpl::AbstractKeccakImpl(
const unsigned size,
46 const bool isSHA3Hash) :
47 capacityWords((2 * size) / sizeof(uint64_t)), useSHA3Hash(isSHA3Hash)
112 words = len /
sizeof(uint64_t);
113 tail = len - words *
sizeof(uint64_t);
115 for (i = 0; i < words; i++, buf +=
sizeof(uint64_t))
117 const uint64_t t = (uint64_t) (buf[0]) |
118 ((uint64_t) (buf[1]) << 8 * 1) |
119 ((uint64_t) (buf[2]) << 8 * 2) |
120 ((uint64_t) (buf[3]) << 8 * 3) |
121 ((uint64_t) (buf[4]) << 8 * 4) |
122 ((uint64_t) (buf[5]) << 8 * 5) |
123 ((uint64_t) (buf[6]) << 8 * 6) |
124 ((uint64_t) (buf[7]) << 8 * 7);
125 #if defined(__x86_64__ ) || defined(__i386__)
126 assert(memcmp(&t, buf, 8) == 0);
148 void AbstractKeccakImpl::transform()
150 static constexpr
int KECCAK_ROUNDS = 24;
151 static const uint64_t keccakf_rndc[KECCAK_ROUNDS] = {
152 UINT64_C(0x0000000000000001), UINT64_C(0x0000000000008082),
153 UINT64_C(0x800000000000808a), UINT64_C(0x8000000080008000),
154 UINT64_C(0x000000000000808b), UINT64_C(0x0000000080000001),
155 UINT64_C(0x8000000080008081), UINT64_C(0x8000000000008009),
156 UINT64_C(0x000000000000008a), UINT64_C(0x0000000000000088),
157 UINT64_C(0x0000000080008009), UINT64_C(0x000000008000000a),
158 UINT64_C(0x000000008000808b), UINT64_C(0x800000000000008b),
159 UINT64_C(0x8000000000008089), UINT64_C(0x8000000000008003),
160 UINT64_C(0x8000000000008002), UINT64_C(0x8000000000000080),
161 UINT64_C(0x000000000000800a), UINT64_C(0x800000008000000a),
162 UINT64_C(0x8000000080008081), UINT64_C(0x8000000000008080),
163 UINT64_C(0x0000000080000001), UINT64_C(0x8000000080008008)
166 static const unsigned keccakf_rotc[KECCAK_ROUNDS] = {
167 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62,
168 18, 39, 61, 20, 44 };
170 static const unsigned keccakf_piln[KECCAK_ROUNDS] = {
171 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20,
177 for (round = 0; round < KECCAK_ROUNDS; round++)
180 for (i = 0; i < 5; i++)
183 for (i = 0; i < 5; i++)
185 t = bc[(i + 4) % 5] ^ rol(bc[(i + 1) % 5], 1);
186 for (j = 0; j < 25; j += 5)
192 for (i = 0; i < 24; i++)
196 state[j] = rol(t, keccakf_rotc[i]);
201 for (j = 0; j < 25; j += 5)
203 for (i = 0; i < 5; i++)
204 bc[i] =
state[j + i];
205 for (i = 0; i < 5; i++)
206 state[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
210 state[0] ^= keccakf_rndc[round];
231 t = (uint64_t)(((uint64_t) 1) << (
byteIndex * 8));
233 t = (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << ((
byteIndex) * 8));
244 #if (LIBXCKS_BYTE_ORDER != LIBXCKS_LITTLE_ENDIAN)
380 uint8_t* Keccak224::getValue(uint8_t* buffer)
const
382 Keccak224 keccak224(*
this);
385 memcpy(buffer, keccak224.state, getSize());
395 ArrayString Keccak224::getAlternativeNames()
397 return ArrayString{
"Keccak-224" };
410 uint8_t* Keccak256::getValue(uint8_t* buffer)
const
412 Keccak256 keccak256(*
this);
415 memcpy(buffer, keccak256.state, getSize());
440 uint8_t* Keccak384::getValue(uint8_t* buffer)
const
442 Keccak384 keccak384(*
this);
445 memcpy(buffer, keccak384.state, getSize());
470 uint8_t* Keccak512::getValue(uint8_t* buffer)
const
472 Keccak512 keccak512(*
this);
475 memcpy(buffer, keccak512.state, getSize());
void update(const uint8_t *buf, size_t len) override final
Updates the Keccak hash with specified array of bytes.
const bool useSHA3Hash
true if result is SHA3 hash, false if "original" Keccak hash.
unsigned byteIndex
0..7–the next byte after the set one (starts from 0; 0–none are buffered).
unsigned wordIndex
0..24–the next word to integrate input (starts from 0).
void reset() override final
Resets the Keccak hash to initial value.
uint64_t state[SHA3_KECCAK_SPONGE_WORDS]
Keccak's state in 'words'.
void finish()
Process the remaining bytes in the internal buffer and the usual prolog according to the standard.
static constexpr unsigned SHA3_KECCAK_SPONGE_WORDS
'Words' here refers to uint64_t
uint64_t saved
The portion of the input message that we didn't consume yet.
const unsigned capacityWords
The double size of the hash output in words (e.g. 16 for Keccak 512).
static uint32_t swapOnBE(const uint32_t value)
Swaps bytes on big endian architectures.
Computes the SHA3-224 hash from a byte stream.
size_t getSize() const override final
Returns the minimal size to allocate in memory to store the hash with the getValue(buffer) method.
uint8_t * getValue(uint8_t *buffer) const override
Returns the SHA3-224 hash value in the first 28 bytes of the given address.
static ArrayString getAlternativeNames()
Returns the alternative names of the SHA3-224 hash algorithm.
Computes the SHA3-256 hash from a byte stream.
static ArrayString getAlternativeNames()
Returns the alternative names of the SHA3-256 hash algorithm.
size_t getSize() const override final
Returns the minimal size to allocate in memory to store the hash with the getValue(buffer) method.
uint8_t * getValue(uint8_t *buffer) const override
Returns the SHA3-256 hash value in the first 32 bytes of the given address.
Computes the SHA3-384 hash from a byte stream.
size_t getSize() const override final
Returns the minimal size to allocate in memory to store the hash with the getValue(buffer) method.
uint8_t * getValue(uint8_t *buffer) const override final
Returns the SHA3-384 hash value in the first 48 bytes of the given address.
static ArrayString getAlternativeNames()
Returns the alternative names of the SHA3-384 hash algorithm.
Computes the SHA3-512 hash from a byte stream.
static ArrayString getAlternativeNames()
Returns the alternative names of the SHA3-512 hash algorithm.
uint8_t * getValue(uint8_t *buffer) const override final
Returns the SHA3-512 hash value in the first 64 bytes of the given address.
size_t getSize() const override final
Returns the minimal size to allocate in memory to store the hash with the getValue(buffer) method.
Compute Keccak and SHA3 hashes.
std::vector< std::string > ArrayString
Array of strings.