Line | Count | Source (jump to first uncovered line) |
1 | | // shake.cpp - modified by Wei Dai from Ronny Van Keer's public domain |
2 | | // sha3-simple.c. All modifications here are placed in the |
3 | | // public domain by Wei Dai. |
4 | | // Keccack core function moved to keccakc.cpp in AUG 2018 |
5 | | // by Jeffrey Walton. Separating the core file allows both |
6 | | // SHA3 and Keccack to share the core implementation. |
7 | | |
8 | | /* |
9 | | The SHAKE sponge function, designed by Guido Bertoni, Joan Daemen, |
10 | | Michael Peeters and Gilles Van Assche. For more information, feedback or |
11 | | questions, please refer to our website: http://keccak.noekeon.org/ |
12 | | |
13 | | Implementation by Ronny Van Keer, hereby denoted as "the implementer". |
14 | | |
15 | | To the extent possible under law, the implementer has waived all copyright |
16 | | and related or neighboring rights to the source code in this file. |
17 | | http://creativecommons.org/publicdomain/zero/1.0/ |
18 | | */ |
19 | | |
20 | | #include "pch.h" |
21 | | #include "shake.h" |
22 | | |
23 | | NAMESPACE_BEGIN(CryptoPP) |
24 | | |
25 | | // The Keccak core function |
26 | | extern void KeccakF1600(word64 *state); |
27 | | |
28 | | void SHAKE::Update(const byte *input, size_t length) |
29 | 94.1k | { |
30 | 94.1k | CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0)); |
31 | 94.1k | if (length == 0) { return; } |
32 | | |
33 | 58.9k | size_t spaceLeft; |
34 | 387k | while (length >= (spaceLeft = r() - m_counter)) |
35 | 328k | { |
36 | 328k | if (spaceLeft) |
37 | 328k | xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft); |
38 | 328k | KeccakF1600(m_state); |
39 | 328k | input += spaceLeft; |
40 | 328k | length -= spaceLeft; |
41 | 328k | m_counter = 0; |
42 | 328k | } |
43 | | |
44 | 58.9k | if (length) |
45 | 38.0k | xorbuf(m_state.BytePtr() + m_counter, input, length); |
46 | 58.9k | m_counter += (unsigned int)length; |
47 | 58.9k | } |
48 | | |
49 | | void SHAKE::Restart() |
50 | 21.6k | { |
51 | 21.6k | std::memset(m_state, 0, m_state.SizeInBytes()); |
52 | 21.6k | m_counter = 0; |
53 | 21.6k | } |
54 | | |
55 | | void SHAKE::ThrowIfInvalidTruncatedSize(size_t size) const |
56 | 21.2k | { |
57 | 21.2k | if (size > UINT_MAX) |
58 | 0 | throw InvalidArgument(std::string("HashTransformation: can't truncate a ") + |
59 | 0 | IntToString(UINT_MAX) + " byte digest to " + IntToString(size) + " bytes"); |
60 | 21.2k | } |
61 | | |
62 | | void SHAKE::TruncatedFinal(byte *hash, size_t size) |
63 | 21.2k | { |
64 | 21.2k | CRYPTOPP_ASSERT(hash != NULLPTR); |
65 | 21.2k | ThrowIfInvalidTruncatedSize(size); |
66 | | |
67 | 21.2k | m_state.BytePtr()[m_counter] ^= 0x1F; |
68 | 21.2k | m_state.BytePtr()[r()-1] ^= 0x80; |
69 | | |
70 | | // FIPS 202, Algorithm 8, pp 18-19. |
71 | 42.5k | while (size > 0) |
72 | 21.2k | { |
73 | 21.2k | KeccakF1600(m_state); |
74 | | |
75 | 21.2k | const size_t segmentLen = STDMIN(size, (size_t)BlockSize()); |
76 | 21.2k | std::memcpy(hash, m_state, segmentLen); |
77 | | |
78 | 21.2k | hash += segmentLen; |
79 | 21.2k | size -= segmentLen; |
80 | 21.2k | } |
81 | | |
82 | 21.2k | Restart(); |
83 | 21.2k | } |
84 | | |
85 | | NAMESPACE_END |