From 275afb4955b514990abf84b701eee6b0bf2db3e4 Mon Sep 17 00:00:00 2001 From: DevJPM Date: Thu, 21 Apr 2016 23:16:23 +0200 Subject: [PATCH 1/3] Adjusted ChaCha for dynamic round selection I've adjusted the ChaCha code to allow selection of the round number at run-time and to improve readibility (slightly) --- chacha.cpp | 20 +++++++------------ chacha.h | 58 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/chacha.cpp b/chacha.cpp index c5178fe4..5c1c4624 100755 --- a/chacha.cpp +++ b/chacha.cpp @@ -27,8 +27,7 @@ void ChaCha_TestInstantiations() } #endif -template -void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { CRYPTOPP_UNUSED(params); assert(length == 16 || length == 32); @@ -46,8 +45,7 @@ void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *ke get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]); } -template -void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) +void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) { CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length); assert(length==8); @@ -57,8 +55,7 @@ void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV get(m_state[14])(m_state[15]); } -template -void ChaCha_Policy::SeekToIteration(lword iterationCount) +void ChaCha_Policy::SeekToIteration(lword iterationCount) { CRYPTOPP_UNUSED(iterationCount); throw NotImplemented(std::string(ChaCha_Info::StaticAlgorithmName()) + ": SeekToIteration is not yet implemented"); @@ -70,8 +67,7 @@ void ChaCha_Policy::SeekToIteration(lword iterationCount) // m_state[5] = (word32)SafeRightShift<32>(iterationCount); } -template -unsigned int ChaCha_Policy::GetAlignment() const +unsigned int ChaCha_Policy::GetAlignment() const { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && 0 if (HasSSE2()) @@ -81,8 +77,7 @@ unsigned int ChaCha_Policy::GetAlignment() const return GetAlignmentOf(); } -template -unsigned int ChaCha_Policy::GetOptimalBlockSize() const +unsigned int ChaCha_Policy::GetOptimalBlockSize() const { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && 0 if (HasSSE2()) @@ -92,8 +87,7 @@ unsigned int ChaCha_Policy::GetOptimalBlockSize() const return BYTES_PER_ITERATION; } -template -void ChaCha_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +void ChaCha_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) { word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; @@ -104,7 +98,7 @@ void ChaCha_Policy::OperateKeystream(KeystreamOperation operation, byte *outp x8 = m_state[8]; x9 = m_state[9]; x10 = m_state[10]; x11 = m_state[11]; x12 = m_state[12]; x13 = m_state[13]; x14 = m_state[14]; x15 = m_state[15]; - for (int i = static_cast(ROUNDS); i > 0; i -= 2) + for (int i = static_cast(m_rounds); i > 0; i -= 2) { CHACHA_QUARTER_ROUND(x0, x4, x8, x12); CHACHA_QUARTER_ROUND(x1, x5, x9, x13); diff --git a/chacha.h b/chacha.h index 23608070..14982557 100755 --- a/chacha.h +++ b/chacha.h @@ -4,32 +4,37 @@ // family implementation at http://cr.yp.to/chacha.html. //! \file chacha.h -//! \brief Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers +//! \brief Classes for the ChaCha family of stream ciphers #ifndef CRYPTOPP_CHACHA_H #define CRYPTOPP_CHACHA_H #include "strciphr.h" #include "secblock.h" +#include "algparam.h" // for MakeParameters() NAMESPACE_BEGIN(CryptoPP) //! \class ChaCha_Info //! \brief ChaCha stream cipher information -template -struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>, public FixedRounds +struct ChaCha_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> { - static const char *StaticAlgorithmName() {static const std::string name = "ChaCha" + IntToString(R); return name.c_str();} + static const char *StaticAlgorithmName() {static const std::string name = "ChaCha"; return name.c_str();} +}; + +//! \class ChaChaFR_Info +//! \brief ChaCha stream cipher information for compile-time fixed rounds +template +struct ChaChaFR_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8>, public FixedRounds +{ + static const char *StaticAlgorithmName() { static const std::string name = "ChaCha" + IntToString(R); return name.c_str(); } }; //! \class ChaCha_Policy //! \brief ChaCha stream cipher implementation -template class CRYPTOPP_NO_VTABLE ChaCha_Policy : public AdditiveCipherConcretePolicy { protected: - CRYPTOPP_CONSTANT(ROUNDS=FixedRounds::ROUNDS); - void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length); @@ -39,33 +44,54 @@ protected: unsigned int GetOptimalBlockSize() const; FixedSizeAlignedSecBlock m_state; + unsigned int m_rounds; +}; + +//! \class ChaCha_Policy +//! \brief ChaCha stream cipher implementation for fixed rounds +template +class CRYPTOPP_NO_VTABLE ChaChaFR_Policy : public ChaCha_Policy +{ +protected: + CRYPTOPP_CONSTANT(ROUNDS = FixedRounds::ROUNDS); + + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { CRYPTOPP_UNUSED(params); ChaCha_Policy::CipherSetKey(MakeParameters(Name::Rounds(), ROUNDS), key, length); } }; //! \class ChaCha8 //! \brief ChaCha8 stream cipher //! \sa ChaCha, a variant of Salsa20 (2008.01.28). -struct ChaCha8 : public ChaCha_Info<8>, public SymmetricCipherDocumentation +struct ChaCha8 : public ChaChaFR_Info<8>, public SymmetricCipherDocumentation { - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<8> > Encryption; - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<8> > Decryption; + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaChaFR_Info<8> > Encryption; + typedef Encryption Decryption; }; //! \class ChaCha12 //! \brief ChaCha12 stream cipher //! \sa ChaCha, a variant of Salsa20 (2008.01.28). -struct ChaCha12 : public ChaCha_Info<12>, public SymmetricCipherDocumentation +struct ChaCha12 : public ChaChaFR_Info<12>, public SymmetricCipherDocumentation { - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<12> > Encryption; - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<12> > Decryption; + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaChaFR_Info<12> > Encryption; + typedef Encryption Decryption; }; //! \class ChaCha20 //! \brief ChaCha20 stream cipher //! \sa ChaCha, a variant of Salsa20 (2008.01.28). -struct ChaCha20 : public ChaCha_Info<20>, public SymmetricCipherDocumentation +struct ChaCha20 : public ChaChaFR_Info<20>, public SymmetricCipherDocumentation { - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<20> > Encryption; - typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaCha_Info<20> > Decryption; + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, ChaChaFR_Info<20> > Encryption; + typedef Encryption Decryption; +}; + +//! \class ChaCha +//! \brief ChaCha stream cipher +//! \sa ChaCha, a variant of Salsa20 (2008.01.28). +struct ChaCha : public ChaCha_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, ChaCha_Info > Encryption; + typedef Encryption Decryption; }; NAMESPACE_END From 040347968b3c9a77ae095a930d46ef8bf7525d25 Mon Sep 17 00:00:00 2001 From: DevJPM Date: Fri, 22 Apr 2016 15:49:29 +0200 Subject: [PATCH 2/3] Changed behavior to accept keys from NameValuePair Previously the ChaCha main function didn't actually accept the round count from the params argument. This was in the local repo at the time of commitment but somehow didn't get pushed. This is now fixed. --- chacha.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/chacha.cpp b/chacha.cpp index 5c1c4624..40a00406 100755 --- a/chacha.cpp +++ b/chacha.cpp @@ -29,8 +29,10 @@ void ChaCha_TestInstantiations() void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { - CRYPTOPP_UNUSED(params); - assert(length == 16 || length == 32); + m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20); + + if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20)) + throw InvalidRounds(ChaCha::StaticAlgorithmName(), m_rounds); // "expand 16-byte k" or "expand 32-byte k" m_state[0] = 0x61707865; From 7ae41dd708c8de88e5203142c97e8b36a2cab612 Mon Sep 17 00:00:00 2001 From: DevJPM Date: Tue, 26 Apr 2016 21:55:33 +0200 Subject: [PATCH 3/3] Fixed ChaCha code --- chacha.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/chacha.cpp b/chacha.cpp index 5c1c4624..9cf298cc 100755 --- a/chacha.cpp +++ b/chacha.cpp @@ -29,7 +29,11 @@ void ChaCha_TestInstantiations() void ChaCha_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { - CRYPTOPP_UNUSED(params); + m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20); + + if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20)) + throw InvalidRounds(ChaCha::StaticAlgorithmName(), m_rounds); + assert(length == 16 || length == 32); // "expand 16-byte k" or "expand 32-byte k" @@ -58,7 +62,7 @@ void ChaCha_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, s void ChaCha_Policy::SeekToIteration(lword iterationCount) { CRYPTOPP_UNUSED(iterationCount); - throw NotImplemented(std::string(ChaCha_Info::StaticAlgorithmName()) + ": SeekToIteration is not yet implemented"); + throw NotImplemented(std::string(ChaCha_Info::StaticAlgorithmName()) + ": SeekToIteration is not yet implemented"); // TODO: these were Salsa20, and Wei re-arranged the state array for SSE2 operations. // If we can generate some out-of-band test vectors, then test and implement. Also @@ -138,9 +142,11 @@ void ChaCha_Policy::OperateKeystream(KeystreamOperation operation, byte *output, } } +/* template class ChaCha_Policy<8>; template class ChaCha_Policy<12>; template class ChaCha_Policy<20>; +*/ NAMESPACE_END