Add SHAKE128 and SHAKE256 (GH #805)
parent
3ea29dec45
commit
6b96dfbe3d
|
|
@ -537,6 +537,7 @@ TestVectors/sha3_256_fips_202.txt
|
||||||
TestVectors/sha3_384_fips_202.txt
|
TestVectors/sha3_384_fips_202.txt
|
||||||
TestVectors/sha3_512_fips_202.txt
|
TestVectors/sha3_512_fips_202.txt
|
||||||
TestVectors/sha3_fips_202.txt
|
TestVectors/sha3_fips_202.txt
|
||||||
|
TestVectors/shake.txt
|
||||||
TestVectors/shacal2.txt
|
TestVectors/shacal2.txt
|
||||||
TestVectors/simeck.txt
|
TestVectors/simeck.txt
|
||||||
TestVectors/simon.txt
|
TestVectors/simon.txt
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ Test: TestVectors/seed.txt
|
||||||
Test: TestVectors/sha1_fips_180.txt
|
Test: TestVectors/sha1_fips_180.txt
|
||||||
Test: TestVectors/sha2_fips_180.txt
|
Test: TestVectors/sha2_fips_180.txt
|
||||||
Test: TestVectors/sha3_fips_202.txt
|
Test: TestVectors/sha3_fips_202.txt
|
||||||
|
Test: TestVectors/shake.txt
|
||||||
Test: TestVectors/shacal2.txt
|
Test: TestVectors/shacal2.txt
|
||||||
Test: TestVectors/sha.txt
|
Test: TestVectors/sha.txt
|
||||||
Test: TestVectors/simeck.txt
|
Test: TestVectors/simeck.txt
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
35
chacha.cpp
35
chacha.cpp
|
|
@ -345,9 +345,13 @@ void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key,
|
||||||
CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 16 || length == 32);
|
CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 16 || length == 32);
|
||||||
CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
|
CRYPTOPP_UNUSED(key); CRYPTOPP_UNUSED(length);
|
||||||
|
|
||||||
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20);
|
// Use previous rounds as the default value
|
||||||
if (m_rounds != 20 && m_rounds != 12 && m_rounds != 8)
|
int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
|
||||||
throw InvalidRounds(ChaCha::StaticAlgorithmName(), m_rounds);
|
if (rounds != 20 && rounds != 12 && rounds != 8)
|
||||||
|
throw InvalidRounds(ChaCha::StaticAlgorithmName(), rounds);
|
||||||
|
|
||||||
|
// Latch a good value
|
||||||
|
m_rounds = rounds;
|
||||||
|
|
||||||
// "expand 16-byte k" or "expand 32-byte k"
|
// "expand 16-byte k" or "expand 32-byte k"
|
||||||
m_state[0] = 0x61707865;
|
m_state[0] = 0x61707865;
|
||||||
|
|
@ -425,9 +429,9 @@ void ChaChaTLS_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke
|
||||||
// the function, so we have to use the heavier-weight SetKey to change it.
|
// the function, so we have to use the heavier-weight SetKey to change it.
|
||||||
word64 block;
|
word64 block;
|
||||||
if (params.GetValue("InitialBlock", block))
|
if (params.GetValue("InitialBlock", block))
|
||||||
m_state[CTR] = static_cast<word32>(block);
|
m_counter = static_cast<word32>(block);
|
||||||
else
|
else
|
||||||
m_state[CTR] = 0;
|
m_counter = 0;
|
||||||
|
|
||||||
// State words are defined in RFC 8439, Section 2.3. Key is 32-bytes.
|
// State words are defined in RFC 8439, Section 2.3. Key is 32-bytes.
|
||||||
GetBlock<word32, LittleEndian> get(key);
|
GetBlock<word32, LittleEndian> get(key);
|
||||||
|
|
@ -449,7 +453,7 @@ void ChaChaTLS_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV
|
||||||
|
|
||||||
// State words are defined in RFC 8439, Section 2.3
|
// State words are defined in RFC 8439, Section 2.3
|
||||||
GetBlock<word32, LittleEndian> get(IV);
|
GetBlock<word32, LittleEndian> get(IV);
|
||||||
m_state[12] = m_state[CTR];
|
m_state[12] = m_counter;
|
||||||
get(m_state[13])(m_state[14])(m_state[15]);
|
get(m_state[13])(m_state[14])(m_state[15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,16 +510,19 @@ void XChaCha20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke
|
||||||
{
|
{
|
||||||
CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32);
|
CRYPTOPP_ASSERT(key); CRYPTOPP_ASSERT(length == 32);
|
||||||
|
|
||||||
// XChaCha20 is always 20 rounds. Fetch Rounds() to avoid a spurious failure.
|
// Use previous rounds as the default value
|
||||||
int rounds = params.GetIntValueWithDefault(Name::Rounds(), ROUNDS);
|
int rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
|
||||||
if (rounds != 20)
|
if (rounds != 20 && rounds != 12)
|
||||||
throw InvalidRounds(XChaCha20::StaticAlgorithmName(), rounds);
|
throw InvalidRounds(ChaCha::StaticAlgorithmName(), rounds);
|
||||||
|
|
||||||
|
// Latch a good value
|
||||||
|
m_rounds = rounds;
|
||||||
|
|
||||||
word64 block;
|
word64 block;
|
||||||
if (params.GetValue("InitialBlock", block))
|
if (params.GetValue("InitialBlock", block))
|
||||||
m_state[CTR] = static_cast<word32>(block);
|
m_counter = static_cast<word32>(block);
|
||||||
else
|
else
|
||||||
m_state[CTR] = 1;
|
m_counter = 1;
|
||||||
|
|
||||||
// Stash key away for use in CipherResynchronize
|
// Stash key away for use in CipherResynchronize
|
||||||
GetBlock<word32, LittleEndian> get(key);
|
GetBlock<word32, LittleEndian> get(key);
|
||||||
|
|
@ -548,7 +555,7 @@ void XChaCha20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv
|
||||||
m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
|
m_state[2] = 0x79622d32; m_state[3] = 0x6b206574;
|
||||||
|
|
||||||
// Setup new IV
|
// Setup new IV
|
||||||
m_state[12] = m_state[CTR];
|
m_state[12] = m_counter;
|
||||||
m_state[13] = 0;
|
m_state[13] = 0;
|
||||||
m_state[14] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+16);
|
m_state[14] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+16);
|
||||||
m_state[15] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+20);
|
m_state[15] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, iv+20);
|
||||||
|
|
@ -575,7 +582,7 @@ void XChaCha20_Policy::OperateKeystream(KeystreamOperation operation,
|
||||||
byte *output, const byte *input, size_t iterationCount)
|
byte *output, const byte *input, size_t iterationCount)
|
||||||
{
|
{
|
||||||
ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
|
ChaCha_OperateKeystream(operation, m_state, m_state[12], m_state[13],
|
||||||
ROUNDS, output, input, iterationCount);
|
m_rounds, output, input, iterationCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
NAMESPACE_END
|
NAMESPACE_END
|
||||||
|
|
|
||||||
18
chacha.h
18
chacha.h
|
|
@ -58,7 +58,7 @@ class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy<wor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ChaCha_Policy() {}
|
virtual ~ChaCha_Policy() {}
|
||||||
ChaCha_Policy() : m_rounds(0) {}
|
ChaCha_Policy() : m_rounds(ROUNDS) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
||||||
|
|
@ -72,6 +72,7 @@ protected:
|
||||||
std::string AlgorithmName() const;
|
std::string AlgorithmName() const;
|
||||||
std::string AlgorithmProvider() const;
|
std::string AlgorithmProvider() const;
|
||||||
|
|
||||||
|
CRYPTOPP_CONSTANT(ROUNDS = 20) // Default rounds
|
||||||
FixedSizeAlignedSecBlock<word32, 16> m_state;
|
FixedSizeAlignedSecBlock<word32, 16> m_state;
|
||||||
unsigned int m_rounds;
|
unsigned int m_rounds;
|
||||||
};
|
};
|
||||||
|
|
@ -114,7 +115,7 @@ class CRYPTOPP_NO_VTABLE ChaChaTLS_Policy : public AdditiveCipherConcretePolicy<
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ChaChaTLS_Policy() {}
|
virtual ~ChaChaTLS_Policy() {}
|
||||||
ChaChaTLS_Policy() {}
|
ChaChaTLS_Policy() : m_counter(0) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
||||||
|
|
@ -128,7 +129,8 @@ protected:
|
||||||
std::string AlgorithmName() const;
|
std::string AlgorithmName() const;
|
||||||
std::string AlgorithmProvider() const;
|
std::string AlgorithmProvider() const;
|
||||||
|
|
||||||
FixedSizeAlignedSecBlock<word32, 16+8+1> m_state;
|
FixedSizeAlignedSecBlock<word32, 16+8> m_state;
|
||||||
|
unsigned int m_counter;
|
||||||
CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS)
|
CRYPTOPP_CONSTANT(ROUNDS = ChaChaTLS_Info::ROUNDS)
|
||||||
CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state
|
CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state
|
||||||
CRYPTOPP_CONSTANT(CTR = 24) // Index into m_state
|
CRYPTOPP_CONSTANT(CTR = 24) // Index into m_state
|
||||||
|
|
@ -161,7 +163,7 @@ struct ChaChaTLS : public ChaChaTLS_Info, public SymmetricCipherDocumentation
|
||||||
|
|
||||||
/// \brief XChaCha stream cipher information
|
/// \brief XChaCha stream cipher information
|
||||||
/// \since Crypto++ 8.1
|
/// \since Crypto++ 8.1
|
||||||
struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>, FixedRounds<20>
|
struct XChaCha20_Info : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 24>
|
||||||
{
|
{
|
||||||
/// \brief The algorithm name
|
/// \brief The algorithm name
|
||||||
/// \returns the algorithm name
|
/// \returns the algorithm name
|
||||||
|
|
@ -179,7 +181,7 @@ class CRYPTOPP_NO_VTABLE XChaCha20_Policy : public AdditiveCipherConcretePolicy<
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~XChaCha20_Policy() {}
|
virtual ~XChaCha20_Policy() {}
|
||||||
XChaCha20_Policy() {}
|
XChaCha20_Policy() : m_counter(0), m_rounds(ROUNDS) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
||||||
|
|
@ -193,10 +195,10 @@ protected:
|
||||||
std::string AlgorithmName() const;
|
std::string AlgorithmName() const;
|
||||||
std::string AlgorithmProvider() const;
|
std::string AlgorithmProvider() const;
|
||||||
|
|
||||||
FixedSizeAlignedSecBlock<word32, 16+8+1> m_state;
|
FixedSizeAlignedSecBlock<word32, 16+8> m_state;
|
||||||
CRYPTOPP_CONSTANT(ROUNDS = XChaCha20_Info::ROUNDS)
|
unsigned int m_counter, m_rounds;
|
||||||
|
CRYPTOPP_CONSTANT(ROUNDS = 20) // Default rounds
|
||||||
CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state
|
CRYPTOPP_CONSTANT(KEY = 16) // Index into m_state
|
||||||
CRYPTOPP_CONSTANT(CTR = 24) // Index into m_state
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief XChaCha stream cipher
|
/// \brief XChaCha stream cipher
|
||||||
|
|
|
||||||
13
keccak.h
13
keccak.h
|
|
@ -48,8 +48,6 @@ public:
|
||||||
/// \since Crypto++ 5.6.4
|
/// \since Crypto++ 5.6.4
|
||||||
Keccak(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
|
Keccak(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
|
||||||
unsigned int DigestSize() const {return m_digestSize;}
|
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>();}
|
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
|
||||||
|
|
||||||
void Update(const byte *input, size_t length);
|
void Update(const byte *input, size_t length);
|
||||||
|
|
@ -57,7 +55,7 @@ public:
|
||||||
void TruncatedFinal(byte *hash, size_t size);
|
void TruncatedFinal(byte *hash, size_t size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline unsigned int r() const {return 200 - 2 * m_digestSize;}
|
inline unsigned int r() const {return BlockSize();}
|
||||||
|
|
||||||
FixedSizeSecBlock<word64, 25> m_state;
|
FixedSizeSecBlock<word64, 25> m_state;
|
||||||
unsigned int m_digestSize, m_counter;
|
unsigned int m_digestSize, m_counter;
|
||||||
|
|
@ -77,6 +75,7 @@ public:
|
||||||
Keccak_Final() : Keccak(DIGESTSIZE) {}
|
Keccak_Final() : Keccak(DIGESTSIZE) {}
|
||||||
static std::string StaticAlgorithmName() { return "Keccak-" + IntToString(DIGESTSIZE * 8); }
|
static std::string StaticAlgorithmName() { return "Keccak-" + IntToString(DIGESTSIZE * 8); }
|
||||||
unsigned int BlockSize() const { return BLOCKSIZE; }
|
unsigned int BlockSize() const { return BLOCKSIZE; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
|
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 > (int)T_DigestSize); // this is a general expectation by HMAC
|
||||||
|
|
@ -84,19 +83,19 @@ private:
|
||||||
|
|
||||||
/// \brief Keccak-224 message digest
|
/// \brief Keccak-224 message digest
|
||||||
/// \since Crypto++ 5.6.4
|
/// \since Crypto++ 5.6.4
|
||||||
typedef Keccak_Final<28> Keccak_224;
|
DOCUMENTED_TYPEDEF(Keccak_Final<28>, Keccak_224);
|
||||||
|
|
||||||
/// \brief Keccak-256 message digest
|
/// \brief Keccak-256 message digest
|
||||||
/// \since Crypto++ 5.6.4
|
/// \since Crypto++ 5.6.4
|
||||||
typedef Keccak_Final<32> Keccak_256;
|
DOCUMENTED_TYPEDEF(Keccak_Final<32>, Keccak_256);
|
||||||
|
|
||||||
/// \brief Keccak-384 message digest
|
/// \brief Keccak-384 message digest
|
||||||
/// \since Crypto++ 5.6.4
|
/// \since Crypto++ 5.6.4
|
||||||
typedef Keccak_Final<48> Keccak_384;
|
DOCUMENTED_TYPEDEF(Keccak_Final<48>, Keccak_384);
|
||||||
|
|
||||||
/// \brief Keccak-512 message digest
|
/// \brief Keccak-512 message digest
|
||||||
/// \since Crypto++ 5.6.4
|
/// \since Crypto++ 5.6.4
|
||||||
typedef Keccak_Final<64> Keccak_512;
|
DOCUMENTED_TYPEDEF(Keccak_Final<64>, Keccak_512);
|
||||||
|
|
||||||
NAMESPACE_END
|
NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "keccak.h"
|
#include "keccak.h"
|
||||||
#include "sha3.h"
|
#include "sha3.h"
|
||||||
|
#include "shake.h"
|
||||||
#include "blake2.h"
|
#include "blake2.h"
|
||||||
#include "sha.h"
|
#include "sha.h"
|
||||||
#include "sha3.h"
|
#include "sha3.h"
|
||||||
|
|
@ -109,6 +110,8 @@ void RegisterFactories1()
|
||||||
RegisterDefaultFactoryFor<HashTransformation, SHA3_256>();
|
RegisterDefaultFactoryFor<HashTransformation, SHA3_256>();
|
||||||
RegisterDefaultFactoryFor<HashTransformation, SHA3_384>();
|
RegisterDefaultFactoryFor<HashTransformation, SHA3_384>();
|
||||||
RegisterDefaultFactoryFor<HashTransformation, SHA3_512>();
|
RegisterDefaultFactoryFor<HashTransformation, SHA3_512>();
|
||||||
|
RegisterDefaultFactoryFor<HashTransformation, SHAKE128>();
|
||||||
|
RegisterDefaultFactoryFor<HashTransformation, SHAKE256>();
|
||||||
RegisterDefaultFactoryFor<HashTransformation, SM3>();
|
RegisterDefaultFactoryFor<HashTransformation, SM3>();
|
||||||
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
|
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
|
||||||
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();
|
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();
|
||||||
|
|
|
||||||
12
salsa.cpp
12
salsa.cpp
|
|
@ -112,10 +112,13 @@ std::string Salsa20_Policy::AlgorithmProvider() const
|
||||||
|
|
||||||
void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
||||||
{
|
{
|
||||||
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20);
|
// 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);
|
||||||
|
|
||||||
if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
|
// Latch a good value
|
||||||
throw InvalidRounds(Salsa20::StaticAlgorithmName(), m_rounds);
|
m_rounds = rounds;
|
||||||
|
|
||||||
// m_state is reordered for SSE2
|
// m_state is reordered for SSE2
|
||||||
GetBlock<word32, LittleEndian> get1(key);
|
GetBlock<word32, LittleEndian> get1(key);
|
||||||
|
|
@ -692,8 +695,7 @@ Salsa20_OperateKeystream ENDP
|
||||||
|
|
||||||
void XSalsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
void XSalsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
|
||||||
{
|
{
|
||||||
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20);
|
m_rounds = params.GetIntValueWithDefault(Name::Rounds(), m_rounds);
|
||||||
|
|
||||||
if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
|
if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
|
||||||
throw InvalidRounds(XSalsa20::StaticAlgorithmName(), m_rounds);
|
throw InvalidRounds(XSalsa20::StaticAlgorithmName(), m_rounds);
|
||||||
|
|
||||||
|
|
|
||||||
2
salsa.h
2
salsa.h
|
|
@ -36,6 +36,7 @@ struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInter
|
||||||
class CRYPTOPP_NO_VTABLE Salsa20_Policy : public AdditiveCipherConcretePolicy<word32, 16>
|
class CRYPTOPP_NO_VTABLE Salsa20_Policy : public AdditiveCipherConcretePolicy<word32, 16>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
Salsa20_Policy() : m_rounds(ROUNDS) {}
|
||||||
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length);
|
||||||
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
|
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
|
||||||
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
|
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length);
|
||||||
|
|
@ -49,6 +50,7 @@ protected:
|
||||||
|
|
||||||
std::string AlgorithmProvider() const;
|
std::string AlgorithmProvider() const;
|
||||||
|
|
||||||
|
CRYPTOPP_CONSTANT(ROUNDS = 20) // Default rounds
|
||||||
FixedSizeAlignedSecBlock<word32, 16> m_state;
|
FixedSizeAlignedSecBlock<word32, 16> m_state;
|
||||||
int m_rounds;
|
int m_rounds;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
68
sha3.h
68
sha3.h
|
|
@ -27,27 +27,24 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||||
class SHA3 : public HashTransformation
|
class SHA3 : public HashTransformation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// \brief Construct a SHA3
|
/// \brief Construct a SHA3
|
||||||
/// \param digestSize the digest size, in bytes
|
/// \param digestSize the digest size, in bytes
|
||||||
/// \details SHA3 is the base class for SHA3_224, SHA3_256, SHA3_384 and SHA3_512.
|
/// \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
|
/// Library users should instantiate a derived class, and only use SHA3
|
||||||
/// as a base class reference or pointer.
|
/// as a base class reference or pointer.
|
||||||
SHA3(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
|
SHA3(unsigned int digestSize) : m_digestSize(digestSize) {Restart();}
|
||||||
unsigned int DigestSize() const {return m_digestSize;}
|
unsigned int DigestSize() const {return m_digestSize;}
|
||||||
std::string AlgorithmName() const {return "SHA3-" + IntToString(m_digestSize*8);}
|
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
|
||||||
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "SHA3"; }
|
|
||||||
unsigned int OptimalDataAlignment() const {return GetAlignmentOf<word64>();}
|
|
||||||
|
|
||||||
void Update(const byte *input, size_t length);
|
void Update(const byte *input, size_t length);
|
||||||
void Restart();
|
void Restart();
|
||||||
void TruncatedFinal(byte *hash, size_t size);
|
void TruncatedFinal(byte *hash, size_t size);
|
||||||
|
|
||||||
// unsigned int BlockSize() const { return r(); } // that's the idea behind it
|
|
||||||
protected:
|
protected:
|
||||||
inline unsigned int r() const {return 200 - 2 * m_digestSize;}
|
inline unsigned int r() const {return BlockSize();}
|
||||||
|
|
||||||
FixedSizeSecBlock<word64, 25> m_state;
|
FixedSizeSecBlock<word64, 25> m_state;
|
||||||
unsigned int m_digestSize, m_counter;
|
unsigned int m_digestSize, m_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief SHA3 message digest template
|
/// \brief SHA3 message digest template
|
||||||
|
|
@ -57,47 +54,36 @@ template<unsigned int T_DigestSize>
|
||||||
class SHA3_Final : public SHA3
|
class SHA3_Final : public SHA3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
|
CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize)
|
||||||
CRYPTOPP_CONSTANT(BLOCKSIZE = 200 - 2 * 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:
|
private:
|
||||||
#if !defined(__BORLANDC__)
|
#if !defined(__BORLANDC__)
|
||||||
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); // ensure there was no underflow in the math
|
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 > (int)T_DigestSize); // this is a general expectation by HMAC
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief SHA3-224 message digest
|
/// \brief SHA3-224 message digest
|
||||||
/// \since Crypto++ 5.6.2
|
/// \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
|
/// \brief SHA3-256 message digest
|
||||||
/// \since Crypto++ 5.6.2
|
/// \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
|
/// \brief SHA3-384 message digest
|
||||||
/// \since Crypto++ 5.6.2
|
/// \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
|
/// \brief SHA3-512 message digest
|
||||||
/// \since Crypto++ 5.6.2
|
/// \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
|
NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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++ 6.0
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue