Add SHAKE-128 and SHAKE-256 (GH #805, PR #806)

This commit is contained in:
Jeffrey Walton 2019-02-12 19:51:37 -05:00 committed by GitHub
parent e499131ea6
commit c6e8a61b8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1719 additions and 361 deletions

View File

@ -186,9 +186,9 @@ kalynatab.cpp
kalyna.cpp
kalyna.h
keccak.cpp
keccak_core.cpp
keccak_simd.cpp
keccak.h
keccakc.cpp
keccakc.h
lubyrack.h
lea.cpp
lea_simd.cpp
@ -309,6 +309,8 @@ sha3.h
shacal2.cpp
shacal2_simd.cpp
shacal2.h
shake.cpp
shake.h
shark.cpp
shark.h
sharkbox.cpp
@ -535,6 +537,7 @@ TestVectors/sha3_256_fips_202.txt
TestVectors/sha3_384_fips_202.txt
TestVectors/sha3_512_fips_202.txt
TestVectors/sha3_fips_202.txt
TestVectors/shake.txt
TestVectors/shacal2.txt
TestVectors/simeck.txt
TestVectors/simon.txt

View File

@ -270,6 +270,7 @@ ifeq ($(DETECT_FEATURES),1)
ifeq ($(strip $(HAVE_OPT)),0)
ARIA_FLAG = $(SSSE3_FLAG)
CHAM_FLAG = $(SSSE3_FLAG)
KECCAK_FLAG = $(SSSE3_FLAG)
LEA_FLAG = $(SSSE3_FLAG)
SIMECK_FLAG = $(SSSE3_FLAG)
SIMON64_FLAG = $(SSSE3_FLAG)
@ -1475,6 +1476,10 @@ gcm_simd.o : gcm_simd.cpp
gf2n_simd.o : gf2n_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(GF2N_FLAG) -c) $<
# SSSE3 available
keccak_simd.o : keccak_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(KECCAK_FLAG) -c) $<
# SSSE3 available
lea_simd.o : lea_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(LEA_FLAG) -c) $<

View File

@ -43,6 +43,7 @@ Test: TestVectors/seed.txt
Test: TestVectors/sha1_fips_180.txt
Test: TestVectors/sha2_fips_180.txt
Test: TestVectors/sha3_fips_202.txt
Test: TestVectors/shake.txt
Test: TestVectors/shacal2.txt
Test: TestVectors/sha.txt
Test: TestVectors/simeck.txt

1206
TestVectors/shake.txt Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,4 +3,4 @@
<PropertyGroup>
<LocalDebuggerCommandArguments>v</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>
</Project>

View File

@ -257,7 +257,8 @@
<ClCompile Include="kalyna.cpp" />
<ClCompile Include="kalynatab.cpp" />
<ClCompile Include="keccak.cpp" />
<ClCompile Include="keccakc.cpp" />
<ClCompile Include="keccak_core.cpp" />
<ClCompile Include="keccak_simd.cpp" />
<ClCompile Include="lea.cpp" />
<ClCompile Include="lea_simd.cpp" />
<ClCompile Include="luc.cpp" />
@ -309,6 +310,7 @@
<ClCompile Include="sha3.cpp" />
<ClCompile Include="shacal2.cpp" />
<ClCompile Include="shacal2_simd.cpp" />
<ClCompile Include="shake.cpp" />
<ClCompile Include="shark.cpp" />
<ClCompile Include="sharkbox.cpp" />
<ClCompile Include="simeck.cpp" />
@ -460,7 +462,6 @@
<ClInclude Include="iterhash.h" />
<ClInclude Include="kalyna.h" />
<ClInclude Include="keccak.h" />
<ClInclude Include="keccakc.h" />
<ClInclude Include="lubyrack.h" />
<ClInclude Include="lea.h" />
<ClInclude Include="luc.h" />
@ -514,6 +515,7 @@
<ClInclude Include="sha.h" />
<ClInclude Include="sha3.h" />
<ClInclude Include="shacal2.h" />
<ClInclude Include="shake.h" />
<ClInclude Include="shark.h" />
<ClInclude Include="simple.h" />
<ClInclude Include="simeck.h" />

View File

@ -257,7 +257,10 @@
<ClCompile Include="keccak.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="keccakc.cpp">
<ClCompile Include="keccak_core.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="keccak_simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lea.cpp">
@ -407,6 +410,9 @@
<ClCompile Include="shacal2_simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shake.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shark.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -759,9 +765,6 @@
<ClInclude Include="keccak.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="keccakc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lubyrack.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -921,6 +924,9 @@
<ClInclude Include="shacal2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shake.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shark.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -19,10 +19,12 @@ http://creativecommons.org/publicdomain/zero/1.0/
#include "pch.h"
#include "keccak.h"
#include "keccakc.h"
NAMESPACE_BEGIN(CryptoPP)
// The Keccak core function
extern void KeccakF1600(word64 *state);
void Keccak::Update(const byte *input, size_t length)
{
CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0));
@ -52,13 +54,13 @@ void Keccak::Restart()
void Keccak::TruncatedFinal(byte *hash, size_t size)
{
CRYPTOPP_ASSERT(hash != NULLPTR);
CRYPTOPP_ASSERT(hash != NULLPTR);
ThrowIfInvalidTruncatedSize(size);
m_state.BytePtr()[m_counter] ^= 1;
m_state.BytePtr()[m_counter] ^= 0x01;
m_state.BytePtr()[r()-1] ^= 0x80;
KeccakF1600(m_state);
memcpy(hash, m_state, size);
std::memcpy(hash, m_state, size);
Restart();
}

View File

@ -40,29 +40,25 @@ NAMESPACE_BEGIN(CryptoPP)
class Keccak : public HashTransformation
{
public:
/// \brief Construct a Keccak
/// \param digestSize the digest size, in bytes
/// \details Keccak is the base class for Keccak_224, Keccak_256, Keccak_384 and Keccak_512.
/// Library users should instantiate a derived class, and only use Keccak
/// as a base class reference or pointer.
/// \since Crypto++ 5.6.4
Keccak(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
unsigned int DigestSize() const {return m_digestSize;}
std::string AlgorithmName() const {return "Keccak-" + IntToString(m_digestSize*8);}
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "Keccak"; }
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
/// \brief Construct a Keccak
/// \param digestSize the digest size, in bytes
/// \details Keccak is the base class for Keccak_224, Keccak_256, Keccak_384 and Keccak_512.
/// Library users should instantiate a derived class, and only use Keccak
/// as a base class reference or pointer.
/// \since Crypto++ 5.6.4
Keccak(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
void Update(const byte *input, size_t length);
void Restart();
void TruncatedFinal(byte *hash, size_t size);
//unsigned int BlockSize() const { return r(); } // that's the idea behind it
void Update(const byte *input, size_t length);
void Restart();
void TruncatedFinal(byte *hash, size_t size);
protected:
inline unsigned int r() const {return 200 - 2 * m_digestSize;}
inline unsigned int r() const {return BlockSize();}
FixedSizeSecBlock<word64, 25> m_state;
unsigned int m_digestSize, m_counter;
FixedSizeSecBlock<word64, 25> m_state;
unsigned int m_digestSize, m_counter;
};
/// \brief Keccak message digest template
@ -72,33 +68,34 @@ template<unsigned int T_DigestSize>
class Keccak_Final : public Keccak
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE)
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE)
/// \brief Construct a Keccak-X message digest
Keccak_Final() : Keccak(DIGESTSIZE) {}
static std::string StaticAlgorithmName() { return "Keccak-" + IntToString(DIGESTSIZE * 8); }
unsigned int BlockSize() const { return BLOCKSIZE; }
/// \brief Construct a Keccak-X message digest
Keccak_Final() : Keccak(DIGESTSIZE) {}
static std::string StaticAlgorithmName() { return "Keccak-" + IntToString(DIGESTSIZE * 8); }
unsigned int BlockSize() const { return BLOCKSIZE; }
private:
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE > (int)T_DigestSize); // this is a general expectation by HMAC
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE > (int)T_DigestSize); // this is a general expectation by HMAC
};
/// \brief Keccak-224 message digest
/// \since Crypto++ 5.6.4
typedef Keccak_Final<28> Keccak_224;
DOCUMENTED_TYPEDEF(Keccak_Final<28>, Keccak_224);
/// \brief Keccak-256 message digest
/// \since Crypto++ 5.6.4
typedef Keccak_Final<32> Keccak_256;
DOCUMENTED_TYPEDEF(Keccak_Final<32>, Keccak_256);
/// \brief Keccak-384 message digest
/// \since Crypto++ 5.6.4
typedef Keccak_Final<48> Keccak_384;
DOCUMENTED_TYPEDEF(Keccak_Final<48>, Keccak_384);
/// \brief Keccak-512 message digest
/// \since Crypto++ 5.6.4
typedef Keccak_Final<64> Keccak_512;
DOCUMENTED_TYPEDEF(Keccak_Final<64>, Keccak_512);
NAMESPACE_END

261
keccak_core.cpp Normal file
View File

@ -0,0 +1,261 @@
// keccakc.cpp - Keccak core functions shared between SHA3 and Keccak.
// written and placed in the public domain by JW.
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michael Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer, hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "pch.h"
#include "keccak.h"
NAMESPACE_BEGIN(CryptoPP)
// The Keccak core function
extern void KeccakF1600(word64 *state);
// The F1600 round constants
extern const word64 KeccakF1600Constants[24];
NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
CRYPTOPP_ALIGN_DATA(8)
const word64 KeccakF1600Constants[24] =
{
W64LIT(0x0000000000000001), W64LIT(0x0000000000008082),
W64LIT(0x800000000000808a), W64LIT(0x8000000080008000),
W64LIT(0x000000000000808b), W64LIT(0x0000000080000001),
W64LIT(0x8000000080008081), W64LIT(0x8000000000008009),
W64LIT(0x000000000000008a), W64LIT(0x0000000000000088),
W64LIT(0x0000000080008009), W64LIT(0x000000008000000a),
W64LIT(0x000000008000808b), W64LIT(0x800000000000008b),
W64LIT(0x8000000000008089), W64LIT(0x8000000000008003),
W64LIT(0x8000000000008002), W64LIT(0x8000000000000080),
W64LIT(0x000000000000800a), W64LIT(0x800000008000000a),
W64LIT(0x8000000080008081), W64LIT(0x8000000000008080),
W64LIT(0x0000000080000001), W64LIT(0x8000000080008008)
};
void KeccakF1600(word64 *state)
{
word64 Aba, Abe, Abi, Abo, Abu;
word64 Aga, Age, Agi, Ago, Agu;
word64 Aka, Ake, Aki, Ako, Aku;
word64 Ama, Ame, Ami, Amo, Amu;
word64 Asa, Ase, Asi, Aso, Asu;
word64 BCa, BCe, BCi, BCo, BCu;
word64 Da, De, Di, Do, Du;
word64 Eba, Ebe, Ebi, Ebo, Ebu;
word64 Ega, Ege, Egi, Ego, Egu;
word64 Eka, Eke, Eki, Eko, Eku;
word64 Ema, Eme, Emi, Emo, Emu;
word64 Esa, Ese, Esi, Eso, Esu;
typedef BlockGetAndPut<word64, LittleEndian, true, true> Block;
Block::Get(state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
for( unsigned int round = 0; round < 24; round += 2 )
{
// prepareTheta
BCa = Aba^Aga^Aka^Ama^Asa;
BCe = Abe^Age^Ake^Ame^Ase;
BCi = Abi^Agi^Aki^Ami^Asi;
BCo = Abo^Ago^Ako^Amo^Aso;
BCu = Abu^Agu^Aku^Amu^Asu;
//thetaRhoPiChiIotaPrepareTheta(round , A, E)
Da = BCu^rotlConstant<1>(BCe);
De = BCa^rotlConstant<1>(BCi);
Di = BCe^rotlConstant<1>(BCo);
Do = BCi^rotlConstant<1>(BCu);
Du = BCo^rotlConstant<1>(BCa);
Aba ^= Da;
BCa = Aba;
Age ^= De;
BCe = rotlConstant<44>(Age);
Aki ^= Di;
BCi = rotlConstant<43>(Aki);
Amo ^= Do;
BCo = rotlConstant<21>(Amo);
Asu ^= Du;
BCu = rotlConstant<14>(Asu);
Eba = BCa ^((~BCe)& BCi );
Eba ^= KeccakF1600Constants[round];
Ebe = BCe ^((~BCi)& BCo );
Ebi = BCi ^((~BCo)& BCu );
Ebo = BCo ^((~BCu)& BCa );
Ebu = BCu ^((~BCa)& BCe );
Abo ^= Do;
BCa = rotlConstant<28>(Abo);
Agu ^= Du;
BCe = rotlConstant<20>(Agu);
Aka ^= Da;
BCi = rotlConstant<3>(Aka);
Ame ^= De;
BCo = rotlConstant<45>(Ame);
Asi ^= Di;
BCu = rotlConstant<61>(Asi);
Ega = BCa ^((~BCe)& BCi );
Ege = BCe ^((~BCi)& BCo );
Egi = BCi ^((~BCo)& BCu );
Ego = BCo ^((~BCu)& BCa );
Egu = BCu ^((~BCa)& BCe );
Abe ^= De;
BCa = rotlConstant<1>(Abe);
Agi ^= Di;
BCe = rotlConstant<6>(Agi);
Ako ^= Do;
BCi = rotlConstant<25>(Ako);
Amu ^= Du;
BCo = rotlConstant<8>(Amu);
Asa ^= Da;
BCu = rotlConstant<18>(Asa);
Eka = BCa ^((~BCe)& BCi );
Eke = BCe ^((~BCi)& BCo );
Eki = BCi ^((~BCo)& BCu );
Eko = BCo ^((~BCu)& BCa );
Eku = BCu ^((~BCa)& BCe );
Abu ^= Du;
BCa = rotlConstant<27>(Abu);
Aga ^= Da;
BCe = rotlConstant<36>(Aga);
Ake ^= De;
BCi = rotlConstant<10>(Ake);
Ami ^= Di;
BCo = rotlConstant<15>(Ami);
Aso ^= Do;
BCu = rotlConstant<56>(Aso);
Ema = BCa ^((~BCe)& BCi );
Eme = BCe ^((~BCi)& BCo );
Emi = BCi ^((~BCo)& BCu );
Emo = BCo ^((~BCu)& BCa );
Emu = BCu ^((~BCa)& BCe );
Abi ^= Di;
BCa = rotlConstant<62>(Abi);
Ago ^= Do;
BCe = rotlConstant<55>(Ago);
Aku ^= Du;
BCi = rotlConstant<39>(Aku);
Ama ^= Da;
BCo = rotlConstant<41>(Ama);
Ase ^= De;
BCu = rotlConstant<2>(Ase);
Esa = BCa ^((~BCe)& BCi );
Ese = BCe ^((~BCi)& BCo );
Esi = BCi ^((~BCo)& BCu );
Eso = BCo ^((~BCu)& BCa );
Esu = BCu ^((~BCa)& BCe );
// prepareTheta
BCa = Eba^Ega^Eka^Ema^Esa;
BCe = Ebe^Ege^Eke^Eme^Ese;
BCi = Ebi^Egi^Eki^Emi^Esi;
BCo = Ebo^Ego^Eko^Emo^Eso;
BCu = Ebu^Egu^Eku^Emu^Esu;
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
Da = BCu^rotlConstant<1>(BCe);
De = BCa^rotlConstant<1>(BCi);
Di = BCe^rotlConstant<1>(BCo);
Do = BCi^rotlConstant<1>(BCu);
Du = BCo^rotlConstant<1>(BCa);
Eba ^= Da;
BCa = Eba;
Ege ^= De;
BCe = rotlConstant<44>(Ege);
Eki ^= Di;
BCi = rotlConstant<43>(Eki);
Emo ^= Do;
BCo = rotlConstant<21>(Emo);
Esu ^= Du;
BCu = rotlConstant<14>(Esu);
Aba = BCa ^((~BCe)& BCi );
Aba ^= KeccakF1600Constants[round+1];
Abe = BCe ^((~BCi)& BCo );
Abi = BCi ^((~BCo)& BCu );
Abo = BCo ^((~BCu)& BCa );
Abu = BCu ^((~BCa)& BCe );
Ebo ^= Do;
BCa = rotlConstant<28>(Ebo);
Egu ^= Du;
BCe = rotlConstant<20>(Egu);
Eka ^= Da;
BCi = rotlConstant<3>(Eka);
Eme ^= De;
BCo = rotlConstant<45>(Eme);
Esi ^= Di;
BCu = rotlConstant<61>(Esi);
Aga = BCa ^((~BCe)& BCi );
Age = BCe ^((~BCi)& BCo );
Agi = BCi ^((~BCo)& BCu );
Ago = BCo ^((~BCu)& BCa );
Agu = BCu ^((~BCa)& BCe );
Ebe ^= De;
BCa = rotlConstant<1>(Ebe);
Egi ^= Di;
BCe = rotlConstant<6>(Egi);
Eko ^= Do;
BCi = rotlConstant<25>(Eko);
Emu ^= Du;
BCo = rotlConstant<8>(Emu);
Esa ^= Da;
BCu = rotlConstant<18>(Esa);
Aka = BCa ^((~BCe)& BCi );
Ake = BCe ^((~BCi)& BCo );
Aki = BCi ^((~BCo)& BCu );
Ako = BCo ^((~BCu)& BCa );
Aku = BCu ^((~BCa)& BCe );
Ebu ^= Du;
BCa = rotlConstant<27>(Ebu);
Ega ^= Da;
BCe = rotlConstant<36>(Ega);
Eke ^= De;
BCi = rotlConstant<10>(Eke);
Emi ^= Di;
BCo = rotlConstant<15>(Emi);
Eso ^= Do;
BCu = rotlConstant<56>(Eso);
Ama = BCa ^((~BCe)& BCi );
Ame = BCe ^((~BCi)& BCo );
Ami = BCi ^((~BCo)& BCu );
Amo = BCo ^((~BCu)& BCa );
Amu = BCu ^((~BCa)& BCe );
Ebi ^= Di;
BCa = rotlConstant<62>(Ebi);
Ego ^= Do;
BCe = rotlConstant<55>(Ego);
Eku ^= Du;
BCi = rotlConstant<39>(Eku);
Ema ^= Da;
BCo = rotlConstant<41>(Ema);
Ese ^= De;
BCu = rotlConstant<2>(Ese);
Asa = BCa ^((~BCe)& BCi );
Ase = BCe ^((~BCi)& BCo );
Asi = BCi ^((~BCo)& BCu );
Aso = BCo ^((~BCu)& BCa );
Asu = BCu ^((~BCa)& BCe );
}
Block::Put(NULLPTR, state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
}
NAMESPACE_END

View File

@ -1,258 +0,0 @@
// keccakc.cpp - Keccak core functions shared between SHA3 and Keccak.
// written and placed in the public domain by JW.
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michael Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer, hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "pch.h"
#include "keccak.h"
#include "keccakc.h"
ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::word64;
const word64 KeccakF_RoundConstants[24] =
{
W64LIT(0x0000000000000001), W64LIT(0x0000000000008082), W64LIT(0x800000000000808a),
W64LIT(0x8000000080008000), W64LIT(0x000000000000808b), W64LIT(0x0000000080000001),
W64LIT(0x8000000080008081), W64LIT(0x8000000000008009), W64LIT(0x000000000000008a),
W64LIT(0x0000000000000088), W64LIT(0x0000000080008009), W64LIT(0x000000008000000a),
W64LIT(0x000000008000808b), W64LIT(0x800000000000008b), W64LIT(0x8000000000008089),
W64LIT(0x8000000000008003), W64LIT(0x8000000000008002), W64LIT(0x8000000000000080),
W64LIT(0x000000000000800a), W64LIT(0x800000008000000a), W64LIT(0x8000000080008081),
W64LIT(0x8000000000008080), W64LIT(0x0000000080000001), W64LIT(0x8000000080008008)
};
ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
void KeccakF1600(word64 *state)
{
{
word64 Aba, Abe, Abi, Abo, Abu;
word64 Aga, Age, Agi, Ago, Agu;
word64 Aka, Ake, Aki, Ako, Aku;
word64 Ama, Ame, Ami, Amo, Amu;
word64 Asa, Ase, Asi, Aso, Asu;
word64 BCa, BCe, BCi, BCo, BCu;
word64 Da, De, Di, Do, Du;
word64 Eba, Ebe, Ebi, Ebo, Ebu;
word64 Ega, Ege, Egi, Ego, Egu;
word64 Eka, Eke, Eki, Eko, Eku;
word64 Ema, Eme, Emi, Emo, Emu;
word64 Esa, Ese, Esi, Eso, Esu;
//copyFromState(A, state)
typedef BlockGetAndPut<word64, LittleEndian, true, true> Block;
Block::Get(state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
for( unsigned int round = 0; round < 24; round += 2 )
{
// prepareTheta
BCa = Aba^Aga^Aka^Ama^Asa;
BCe = Abe^Age^Ake^Ame^Ase;
BCi = Abi^Agi^Aki^Ami^Asi;
BCo = Abo^Ago^Ako^Amo^Aso;
BCu = Abu^Agu^Aku^Amu^Asu;
//thetaRhoPiChiIotaPrepareTheta(round , A, E)
Da = BCu^rotlConstant<1>(BCe);
De = BCa^rotlConstant<1>(BCi);
Di = BCe^rotlConstant<1>(BCo);
Do = BCi^rotlConstant<1>(BCu);
Du = BCo^rotlConstant<1>(BCa);
Aba ^= Da;
BCa = Aba;
Age ^= De;
BCe = rotlConstant<44>(Age);
Aki ^= Di;
BCi = rotlConstant<43>(Aki);
Amo ^= Do;
BCo = rotlConstant<21>(Amo);
Asu ^= Du;
BCu = rotlConstant<14>(Asu);
Eba = BCa ^((~BCe)& BCi );
Eba ^= (word64)KeccakF_RoundConstants[round];
Ebe = BCe ^((~BCi)& BCo );
Ebi = BCi ^((~BCo)& BCu );
Ebo = BCo ^((~BCu)& BCa );
Ebu = BCu ^((~BCa)& BCe );
Abo ^= Do;
BCa = rotlConstant<28>(Abo);
Agu ^= Du;
BCe = rotlConstant<20>(Agu);
Aka ^= Da;
BCi = rotlConstant<3>(Aka);
Ame ^= De;
BCo = rotlConstant<45>(Ame);
Asi ^= Di;
BCu = rotlConstant<61>(Asi);
Ega = BCa ^((~BCe)& BCi );
Ege = BCe ^((~BCi)& BCo );
Egi = BCi ^((~BCo)& BCu );
Ego = BCo ^((~BCu)& BCa );
Egu = BCu ^((~BCa)& BCe );
Abe ^= De;
BCa = rotlConstant<1>(Abe);
Agi ^= Di;
BCe = rotlConstant<6>(Agi);
Ako ^= Do;
BCi = rotlConstant<25>(Ako);
Amu ^= Du;
BCo = rotlConstant<8>(Amu);
Asa ^= Da;
BCu = rotlConstant<18>(Asa);
Eka = BCa ^((~BCe)& BCi );
Eke = BCe ^((~BCi)& BCo );
Eki = BCi ^((~BCo)& BCu );
Eko = BCo ^((~BCu)& BCa );
Eku = BCu ^((~BCa)& BCe );
Abu ^= Du;
BCa = rotlConstant<27>(Abu);
Aga ^= Da;
BCe = rotlConstant<36>(Aga);
Ake ^= De;
BCi = rotlConstant<10>(Ake);
Ami ^= Di;
BCo = rotlConstant<15>(Ami);
Aso ^= Do;
BCu = rotlConstant<56>(Aso);
Ema = BCa ^((~BCe)& BCi );
Eme = BCe ^((~BCi)& BCo );
Emi = BCi ^((~BCo)& BCu );
Emo = BCo ^((~BCu)& BCa );
Emu = BCu ^((~BCa)& BCe );
Abi ^= Di;
BCa = rotlConstant<62>(Abi);
Ago ^= Do;
BCe = rotlConstant<55>(Ago);
Aku ^= Du;
BCi = rotlConstant<39>(Aku);
Ama ^= Da;
BCo = rotlConstant<41>(Ama);
Ase ^= De;
BCu = rotlConstant<2>(Ase);
Esa = BCa ^((~BCe)& BCi );
Ese = BCe ^((~BCi)& BCo );
Esi = BCi ^((~BCo)& BCu );
Eso = BCo ^((~BCu)& BCa );
Esu = BCu ^((~BCa)& BCe );
// prepareTheta
BCa = Eba^Ega^Eka^Ema^Esa;
BCe = Ebe^Ege^Eke^Eme^Ese;
BCi = Ebi^Egi^Eki^Emi^Esi;
BCo = Ebo^Ego^Eko^Emo^Eso;
BCu = Ebu^Egu^Eku^Emu^Esu;
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
Da = BCu^rotlConstant<1>(BCe);
De = BCa^rotlConstant<1>(BCi);
Di = BCe^rotlConstant<1>(BCo);
Do = BCi^rotlConstant<1>(BCu);
Du = BCo^rotlConstant<1>(BCa);
Eba ^= Da;
BCa = Eba;
Ege ^= De;
BCe = rotlConstant<44>(Ege);
Eki ^= Di;
BCi = rotlConstant<43>(Eki);
Emo ^= Do;
BCo = rotlConstant<21>(Emo);
Esu ^= Du;
BCu = rotlConstant<14>(Esu);
Aba = BCa ^((~BCe)& BCi );
Aba ^= (word64)KeccakF_RoundConstants[round+1];
Abe = BCe ^((~BCi)& BCo );
Abi = BCi ^((~BCo)& BCu );
Abo = BCo ^((~BCu)& BCa );
Abu = BCu ^((~BCa)& BCe );
Ebo ^= Do;
BCa = rotlConstant<28>(Ebo);
Egu ^= Du;
BCe = rotlConstant<20>(Egu);
Eka ^= Da;
BCi = rotlConstant<3>(Eka);
Eme ^= De;
BCo = rotlConstant<45>(Eme);
Esi ^= Di;
BCu = rotlConstant<61>(Esi);
Aga = BCa ^((~BCe)& BCi );
Age = BCe ^((~BCi)& BCo );
Agi = BCi ^((~BCo)& BCu );
Ago = BCo ^((~BCu)& BCa );
Agu = BCu ^((~BCa)& BCe );
Ebe ^= De;
BCa = rotlConstant<1>(Ebe);
Egi ^= Di;
BCe = rotlConstant<6>(Egi);
Eko ^= Do;
BCi = rotlConstant<25>(Eko);
Emu ^= Du;
BCo = rotlConstant<8>(Emu);
Esa ^= Da;
BCu = rotlConstant<18>(Esa);
Aka = BCa ^((~BCe)& BCi );
Ake = BCe ^((~BCi)& BCo );
Aki = BCi ^((~BCo)& BCu );
Ako = BCo ^((~BCu)& BCa );
Aku = BCu ^((~BCa)& BCe );
Ebu ^= Du;
BCa = rotlConstant<27>(Ebu);
Ega ^= Da;
BCe = rotlConstant<36>(Ega);
Eke ^= De;
BCi = rotlConstant<10>(Eke);
Emi ^= Di;
BCo = rotlConstant<15>(Emi);
Eso ^= Do;
BCu = rotlConstant<56>(Eso);
Ama = BCa ^((~BCe)& BCi );
Ame = BCe ^((~BCi)& BCo );
Ami = BCi ^((~BCo)& BCu );
Amo = BCo ^((~BCu)& BCa );
Amu = BCu ^((~BCa)& BCe );
Ebi ^= Di;
BCa = rotlConstant<62>(Ebi);
Ego ^= Do;
BCe = rotlConstant<55>(Ego);
Eku ^= Du;
BCi = rotlConstant<39>(Eku);
Ema ^= Da;
BCo = rotlConstant<41>(Ema);
Ese ^= De;
BCu = rotlConstant<2>(Ese);
Asa = BCa ^((~BCe)& BCi );
Ase = BCe ^((~BCi)& BCo );
Asi = BCi ^((~BCo)& BCu );
Aso = BCo ^((~BCu)& BCa );
Asu = BCu ^((~BCa)& BCe );
}
//copyToState(state, A)
Block::Put(NULLPTR, state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
}
}
NAMESPACE_END

View File

@ -1,13 +0,0 @@
// keccakc.h - Keccak core functions shared between SHA3 and Keccak.
// written and placed in the public domain by JW.
#ifndef CRYPTOPP_KECCAK_CORE
#define CRYPTOPP_KECCAK_CORE
NAMESPACE_BEGIN(CryptoPP)
void KeccakF1600(word64 *state);
NAMESPACE_END
#endif // CRYPTOPP_KECCAK_CORE

View File

@ -15,6 +15,7 @@
#include "md5.h"
#include "keccak.h"
#include "sha3.h"
#include "shake.h"
#include "blake2.h"
#include "sha.h"
#include "sha3.h"
@ -109,6 +110,8 @@ void RegisterFactories1()
RegisterDefaultFactoryFor<HashTransformation, SHA3_256>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_384>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_512>();
RegisterDefaultFactoryFor<HashTransformation, SHAKE128>();
RegisterDefaultFactoryFor<HashTransformation, SHAKE256>();
RegisterDefaultFactoryFor<HashTransformation, SM3>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();

View File

@ -112,9 +112,13 @@ std::string Salsa20_Policy::AlgorithmProvider() const
void Salsa20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
{
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
throw InvalidRounds(Salsa20::StaticAlgorithmName(), m_rounds);
// Use previous rounds as the default value
int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
if (rounds != 20 && rounds != 12 && rounds != 8)
throw InvalidRounds(Salsa20::StaticAlgorithmName(), rounds);
// Latch a good value
m_rounds = rounds;
// m_state is reordered for SSE2
GetBlock<word32, LittleEndian> get1(key);

View File

@ -19,7 +19,13 @@ http://creativecommons.org/publicdomain/zero/1.0/
#include "pch.h"
#include "sha3.h"
#include "keccakc.h"
NAMESPACE_BEGIN(CryptoPP)
// The Keccak core function
extern void KeccakF1600(word64 *state);
NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
@ -58,7 +64,7 @@ void SHA3::TruncatedFinal(byte *hash, size_t size)
m_state.BytePtr()[m_counter] ^= 0x06;
m_state.BytePtr()[r()-1] ^= 0x80;
KeccakF1600(m_state);
memcpy(hash, m_state, size);
std::memcpy(hash, m_state, size);
Restart();
}

68
sha3.h
View File

@ -27,27 +27,24 @@ NAMESPACE_BEGIN(CryptoPP)
class SHA3 : public HashTransformation
{
public:
/// \brief Construct a SHA3
/// \param digestSize the digest size, in bytes
/// \details SHA3 is the base class for SHA3_224, SHA3_256, SHA3_384 and SHA3_512.
/// Library users should instantiate a derived class, and only use SHA3
/// as a base class reference or pointer.
SHA3(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
unsigned int DigestSize() const {return m_digestSize;}
std::string AlgorithmName() const {return "SHA3-" + IntToString(m_digestSize*8);}
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "SHA3"; }
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
/// \brief Construct a SHA3
/// \param digestSize the digest size, in bytes
/// \details SHA3 is the base class for SHA3_224, SHA3_256, SHA3_384 and SHA3_512.
/// Library users should instantiate a derived class, and only use SHA3
/// as a base class reference or pointer.
SHA3(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
void Update(const byte *input, size_t length);
void Restart();
void TruncatedFinal(byte *hash, size_t size);
void Update(const byte *input, size_t length);
void Restart();
void TruncatedFinal(byte *hash, size_t size);
// unsigned int BlockSize() const { return r(); } // that's the idea behind it
protected:
inline unsigned int r() const {return 200 - 2 * m_digestSize;}
inline unsigned int r() const {return BlockSize();}
FixedSizeSecBlock<word64, 25> m_state;
unsigned int m_digestSize, m_counter;
FixedSizeSecBlock<word64, 25> m_state;
unsigned int m_digestSize, m_counter;
};
/// \brief SHA3 message digest template
@ -57,47 +54,36 @@ template<unsigned int T_DigestSize>
class SHA3_Final : public SHA3
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE)
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * DIGESTSIZE)
/// \brief Construct a SHA3-X message digest
SHA3_Final() : SHA3(DIGESTSIZE) {}
static std::string StaticAlgorithmName() { return "SHA3-" + IntToString(DIGESTSIZE * 8); }
unsigned int BlockSize() const { return BLOCKSIZE; }
/// \brief Construct a SHA3-X message digest
SHA3_Final() : SHA3(DIGESTSIZE) {}
static std::string StaticAlgorithmName() { return "SHA3-" + IntToString(DIGESTSIZE * 8); }
unsigned int BlockSize() const { return BLOCKSIZE; }
private:
#if !defined(__BORLANDC__)
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE > (int)T_DigestSize); // this is a general expectation by HMAC
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE > (int)T_DigestSize); // this is a general expectation by HMAC
#endif
};
/// \brief SHA3-224 message digest
/// \since Crypto++ 5.6.2
// typedef SHA3_Final<28> SHA3_224;
class SHA3_224 : public SHA3_Final<28>
{
};
class SHA3_224 : public SHA3_Final<28> {};
/// \brief SHA3-256 message digest
/// \since Crypto++ 5.6.2
// typedef SHA3_Final<32> SHA3_256;
class SHA3_256 : public SHA3_Final<32>
{
};
class SHA3_256 : public SHA3_Final<32> {};
/// \brief SHA3-384 message digest
/// \since Crypto++ 5.6.2
// typedef SHA3_Final<48> SHA3_384;
class SHA3_384 : public SHA3_Final<48>
{
};
class SHA3_384 : public SHA3_Final<48> {};
/// \brief SHA3-512 message digest
/// \since Crypto++ 5.6.2
// typedef SHA3_Final<64> SHA3_512;
class SHA3_512 : public SHA3_Final<64>
{
};
class SHA3_512 : public SHA3_Final<64> {};
NAMESPACE_END

67
shake.cpp Normal file
View File

@ -0,0 +1,67 @@
// shake.cpp - modified by Wei Dai from Ronny Van Keer's public domain
// sha3-simple.c. All modifications here are placed in the
// public domain by Wei Dai.
// Keccack core function moved to keccakc.cpp in AUG 2018
// by Jeffrey Walton. Separating the core file allows both
// SHA3 and Keccack to share the core implementation.
/*
The SHAKE sponge function, designed by Guido Bertoni, Joan Daemen,
Michael Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer, hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "pch.h"
#include "shake.h"
NAMESPACE_BEGIN(CryptoPP)
// The Keccak core function
extern void KeccakF1600(word64 *state);
void SHAKE::Update(const byte *input, size_t length)
{
CRYPTOPP_ASSERT(!(input == NULLPTR && length != 0));
if (length == 0) { return; }
size_t spaceLeft;
while (length >= (spaceLeft = r() - m_counter))
{
if (spaceLeft)
xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
KeccakF1600(m_state);
input += spaceLeft;
length -= spaceLeft;
m_counter = 0;
}
if (length)
xorbuf(m_state.BytePtr() + m_counter, input, length);
m_counter += (unsigned int)length;
}
void SHAKE::Restart()
{
memset(m_state, 0, m_state.SizeInBytes());
m_counter = 0;
}
void SHAKE::TruncatedFinal(byte *hash, size_t size)
{
CRYPTOPP_ASSERT(hash != NULLPTR);
ThrowIfInvalidTruncatedSize(size);
m_state.BytePtr()[m_counter] ^= 0x1F;
m_state.BytePtr()[r()-1] ^= 0x80;
KeccakF1600(m_state);
std::memcpy(hash, m_state, size);
Restart();
}
NAMESPACE_END

80
shake.h Normal file
View File

@ -0,0 +1,80 @@
// shake.h - originally written and placed in the public domain by Jeffrey Walton
/// \file shake.h
/// \brief Classes for SHAKE message digests
/// \sa SHA3, SHAKE128, SHAKE256,
/// <a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">FIPS 202,
/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</a>
/// \since Crypto++ 8.1
#ifndef CRYPTOPP_SHAKE_H
#define CRYPTOPP_SHAKE_H
#include "cryptlib.h"
#include "secblock.h"
NAMESPACE_BEGIN(CryptoPP)
/// \brief SHAKE message digest base class
/// \details SHAKE is the base class for SHAKE128 and SHAKE258.
/// Library users should instantiate a derived class, and only use SHAKE
/// as a base class reference or pointer.
/// \sa SHA3, SHAKE128, SHAKE256,
/// <a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">FIPS 202,
/// SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</a>
/// \since Crypto++ 8.1
class SHAKE : public HashTransformation
{
public:
/// \brief Construct a SHAKE
/// \param digestSize the digest size, in bytes
/// \details SHAKE is the base class for SHAKE128 and SHAKE256.
/// Library users should instantiate a derived class, and only use SHAKE
/// as a base class reference or pointer.
/// \since Crypto++ 8.1
SHAKE(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
void Update(const byte *input, size_t length);
void Restart();
void TruncatedFinal(byte *hash, size_t size);
protected:
inline unsigned int r() const {return BlockSize();}
FixedSizeSecBlock<word64, 25> m_state;
unsigned int m_digestSize, m_counter;
};
/// \brief SHAKE message digest template
/// \tparam T_Strength the strength of the digest
/// \since Crypto++ 8.1
template<unsigned int T_Strength>
class SHAKE_Final : public SHAKE
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = (T_Strength == 128 ? 32 : 64))
CRYPTOPP_CONSTANT(BLOCKSIZE = (T_Strength == 128 ? 1344/8 : 1088/8))
static std::string StaticAlgorithmName() { return "SHAKE-" + IntToString(T_Strength); }
/// \brief Construct a SHAKE-X message digest
SHAKE_Final() : SHAKE(DIGESTSIZE) {}
unsigned int BlockSize() const { return BLOCKSIZE; }
private:
CRYPTOPP_COMPILE_ASSERT(T_Strength == 128 || T_Strength == 256);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
};
/// \brief SHAKE128 message digest
/// \since Crypto++ 8.1
class SHAKE128 : public SHAKE_Final<128> {};
/// \brief SHAKE256 message digest
/// \since Crypto++ 8.1
class SHAKE256 : public SHAKE_Final<256> {};
NAMESPACE_END
#endif