fix bug in Grouper

add RIPEMD-???, Whirlpool, Shacal2, Camellia, Two-Track MAC (Kevin Springle)
change ChannelSwitch to allow non-blocking input (denis bider)
change Redirector to allow more options (denis bider)
fix MaurerRandomnessTest
optimize MD2 (Kevin Springle)
pull/2/head
weidai 2003-04-15 00:38:48 +00:00
parent b4f6ef8e16
commit d52b49c51f
29 changed files with 2191 additions and 177 deletions

View File

@ -44,7 +44,7 @@ endif
OBJS = $(SRCS:.cpp=.o) OBJS = $(SRCS:.cpp=.o)
# test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?) # test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?)
TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o TESTOBJS = bench.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o
LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS)) LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS))
all: cryptest.exe all: cryptest.exe

View File

@ -26,6 +26,7 @@ Chris Morgan - rijndael.cpp
Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp
Richard De Moliner - safer.cpp Richard De Moliner - safer.cpp
Matthew Skala - twofish.cpp Matthew Skala - twofish.cpp
Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp
Permission to use, copy, modify, and distribute this compilation for Permission to use, copy, modify, and distribute this compilation for
any purpose, including commercial applications, is hereby granted any purpose, including commercial applications, is hereby granted

View File

@ -1,5 +1,9 @@
AlgorithmType: FileList AlgorithmType: FileList
Name: all.txt collection Name: all.txt collection
Test: camelia.txt
Test: shacal2.txt
Test: ttmac.txt
Test: whrlpool.txt
Test: dlies.txt Test: dlies.txt
Test: dsa.txt Test: dsa.txt
Test: dsa_1363.txt Test: dsa_1363.txt

View File

@ -46,6 +46,12 @@ CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32
CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(XMACC_Counter) //!< word32 CRYPTOPP_DEFINE_NAME_STRING(XMACC_Counter) //!< word32
CRYPTOPP_DEFINE_NAME_STRING(InputFileName) //!< const char *
CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) //!< std::istream *
CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) //!< bool
CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) //!< const char *
CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) //!< std::ostream *
CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) //!< bool
DOCUMENTED_NAMESPACE_END DOCUMENTED_NAMESPACE_END

View File

@ -221,7 +221,10 @@ unsigned int Grouper::Put2(const byte *begin, unsigned int length, int messageEn
FILTER_OUTPUT(3, begin, length, 0); FILTER_OUTPUT(3, begin, length, 0);
if (messageEnd) if (messageEnd)
{
FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd); FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
m_counter = 0;
}
FILTER_END_NO_MESSAGE_END FILTER_END_NO_MESSAGE_END
} }

View File

@ -12,6 +12,7 @@
#include "tiger.h" #include "tiger.h"
#include "ripemd.h" #include "ripemd.h"
#include "panama.h" #include "panama.h"
#include "whrlpool.h"
#include "idea.h" #include "idea.h"
#include "des.h" #include "des.h"
#include "rc2.h" #include "rc2.h"
@ -33,10 +34,13 @@
#include "rijndael.h" #include "rijndael.h"
#include "twofish.h" #include "twofish.h"
#include "serpent.h" #include "serpent.h"
#include "shacal2.h"
#include "camellia.h"
#include "hmac.h" #include "hmac.h"
#include "xormac.h" #include "xormac.h"
#include "cbcmac.h" #include "cbcmac.h"
#include "dmac.h" #include "dmac.h"
#include "ttmac.h"
#include "blumshub.h" #include "blumshub.h"
#include "rsa.h" #include "rsa.h"
#include "nr.h" #include "nr.h"
@ -438,7 +442,9 @@ void BenchMarkAll(double t)
BenchMarkKeyless<MD5>("MD5", t); BenchMarkKeyless<MD5>("MD5", t);
BenchMarkKeyless<SHA>("SHA-1", t); BenchMarkKeyless<SHA>("SHA-1", t);
BenchMarkKeyless<SHA256>("SHA-256", t); BenchMarkKeyless<SHA256>("SHA-256", t);
#ifdef WORD64_AVAILABLE
BenchMarkKeyless<SHA512>("SHA-512", t); BenchMarkKeyless<SHA512>("SHA-512", t);
#endif
BenchMarkKeyless<HAVAL3>("HAVAL (pass=3)", t); BenchMarkKeyless<HAVAL3>("HAVAL (pass=3)", t);
BenchMarkKeyless<HAVAL4>("HAVAL (pass=4)", t); BenchMarkKeyless<HAVAL4>("HAVAL (pass=4)", t);
BenchMarkKeyless<HAVAL5>("HAVAL (pass=5)", t); BenchMarkKeyless<HAVAL5>("HAVAL (pass=5)", t);
@ -448,6 +454,9 @@ void BenchMarkAll(double t)
BenchMarkKeyless<RIPEMD160>("RIPE-MD160", t); BenchMarkKeyless<RIPEMD160>("RIPE-MD160", t);
BenchMarkKeyless<PanamaHash<LittleEndian> >("Panama Hash (little endian)", t); BenchMarkKeyless<PanamaHash<LittleEndian> >("Panama Hash (little endian)", t);
BenchMarkKeyless<PanamaHash<BigEndian> >("Panama Hash (big endian)", t); BenchMarkKeyless<PanamaHash<BigEndian> >("Panama Hash (big endian)", t);
#ifdef WORD64_AVAILABLE
BenchMarkKeyless<Whirlpool>("Whirlpool", t);
#endif
BenchMarkKeyed<MDC<MD5>::Encryption>("MDC/MD5", t); BenchMarkKeyed<MDC<MD5>::Encryption>("MDC/MD5", t);
BenchMarkKeyed<LR<MD5>::Encryption>("Luby-Rackoff/MD5", t); BenchMarkKeyed<LR<MD5>::Encryption>("Luby-Rackoff/MD5", t);
BenchMarkKeyed<DES::Encryption>("DES", t); BenchMarkKeyed<DES::Encryption>("DES", t);
@ -490,9 +499,17 @@ void BenchMarkAll(double t)
BenchMarkKeyed<WAKE_OFB<LittleEndian>::Encryption>("WAKE-OFB-LE", t); BenchMarkKeyed<WAKE_OFB<LittleEndian>::Encryption>("WAKE-OFB-LE", t);
BenchMarkKeyed<PanamaCipher<LittleEndian>::Encryption>("Panama Cipher (little endian)", t); BenchMarkKeyed<PanamaCipher<LittleEndian>::Encryption>("Panama Cipher (little endian)", t);
BenchMarkKeyed<PanamaCipher<BigEndian>::Encryption>("Panama Cipher (big endian)", t); BenchMarkKeyed<PanamaCipher<BigEndian>::Encryption>("Panama Cipher (big endian)", t);
BenchMarkKeyedVariable<SHACAL2::Encryption>("SHACAL-2 (128-bit key)", t, 16);
BenchMarkKeyedVariable<SHACAL2::Encryption>("SHACAL-2 (512-bit key)", t, 64);
#ifdef WORD64_AVAILABLE
BenchMarkKeyedVariable<Camellia::Encryption>("Camellia (128-bit key)", t, 16);
BenchMarkKeyedVariable<Camellia::Encryption>("Camellia (192-bit key)", t, 24);
BenchMarkKeyedVariable<Camellia::Encryption>("Camellia (256-bit key)", t, 32);
#endif
BenchMarkKeyed<MD5MAC>("MD5-MAC", t); BenchMarkKeyed<MD5MAC>("MD5-MAC", t);
BenchMarkKeyed<XMACC<MD5> >("XMACC/MD5", t); BenchMarkKeyed<XMACC<MD5> >("XMACC/MD5", t);
BenchMarkKeyed<HMAC<MD5> >("HMAC/MD5", t); BenchMarkKeyed<HMAC<MD5> >("HMAC/MD5", t);
BenchMarkKeyed<TTMAC>("Two-Track-MAC", t);
BenchMarkKeyed<CBC_MAC<Rijndael> >("CBC-MAC/Rijndael", t); BenchMarkKeyed<CBC_MAC<Rijndael> >("CBC-MAC/Rijndael", t);
BenchMarkKeyed<DMAC<Rijndael> >("DMAC/Rijndael", t); BenchMarkKeyed<DMAC<Rijndael> >("DMAC/Rijndael", t);

View File

@ -85,26 +85,20 @@ void MessageSwitch::MessageSeriesEnd(int propagation=-1);
*/ */
#endif #endif
class ChannelRouteIterator
//
// ChannelRouteIterator
//////////////////////////
void ChannelRouteIterator::Reset(const std::string &channel)
{ {
public: m_channel = channel;
typedef ChannelSwitch::RouteMap::const_iterator MapIterator; pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel);
typedef ChannelSwitch::DefaultRouteList::const_iterator ListIterator;
const std::string m_channel;
bool m_useDefault;
MapIterator m_itMapCurrent, m_itMapEnd;
ListIterator m_itListCurrent, m_itListEnd;
ChannelRouteIterator(ChannelSwitch &cs, const std::string &channel)
: m_channel(channel)
{
pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel);
if (range.first == range.second) if (range.first == range.second)
{ {
m_useDefault = true; m_useDefault = true;
m_itListCurrent = cs.m_defaultRoutes.begin(); m_itListCurrent = m_cs.m_defaultRoutes.begin();
m_itListEnd = cs.m_defaultRoutes.end(); m_itListEnd = m_cs.m_defaultRoutes.end();
} }
else else
{ {
@ -112,46 +106,61 @@ public:
m_itMapCurrent = range.first; m_itMapCurrent = range.first;
m_itMapEnd = range.second; m_itMapEnd = range.second;
} }
} }
bool End() const bool ChannelRouteIterator::End() const
{ {
return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
} }
void Next() void ChannelRouteIterator::Next()
{ {
if (m_useDefault) if (m_useDefault)
++m_itListCurrent; ++m_itListCurrent;
else else
++m_itMapCurrent; ++m_itMapCurrent;
} }
BufferedTransformation & Destination() BufferedTransformation & ChannelRouteIterator::Destination()
{ {
return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
} }
const std::string & Channel() const std::string & ChannelRouteIterator::Channel()
{ {
if (m_useDefault) if (m_useDefault)
return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
else else
return m_itMapCurrent->second.second; return m_itMapCurrent->second.second;
} }
};
//
// ChannelSwitch
///////////////////
unsigned int ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking) unsigned int ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{ {
if (!blocking) if (m_blocked)
throw BlockingInputOnly("ChannelSwitch");
ChannelRouteIterator it(*this, channel);
while (!it.End())
{ {
it.Destination().ChannelPut2(it.Channel(), begin, length, messageEnd, blocking); m_blocked = false;
it.Next(); goto WasBlocked;
} }
m_it.Reset(channel);
while (!m_it.End())
{
WasBlocked:
if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking))
{
m_blocked = true;
return 1;
}
m_it.Next();
}
return 0; return 0;
} }
@ -163,51 +172,74 @@ void ChannelSwitch::ChannelInitialize(const std::string &channel, const NameValu
m_defaultRoutes.clear(); m_defaultRoutes.clear();
} }
ChannelRouteIterator it(*this, channel); m_it.Reset(channel);
while (!it.End())
while (!m_it.End())
{ {
it.Destination().ChannelInitialize(it.Channel(), parameters, propagation); m_it.Destination().ChannelInitialize(m_it.Channel(), parameters, propagation);
it.Next(); m_it.Next();
} }
} }
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
{ {
if (!blocking) if (m_blocked)
throw BlockingInputOnly("ChannelSwitch");
ChannelRouteIterator it(*this, channel);
while (!it.End())
{ {
it.Destination().ChannelFlush(it.Channel(), completeFlush, propagation, blocking); m_blocked = false;
it.Next(); goto WasBlocked;
} }
m_it.Reset(channel);
while (!m_it.End())
{
WasBlocked:
if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking))
{
m_blocked = true;
return true;
}
m_it.Next();
}
return false; return false;
} }
bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
{ {
if (!blocking) if (m_blocked)
throw BlockingInputOnly("ChannelSwitch");
ChannelRouteIterator it(*this, channel);
while (!it.End())
{ {
it.Destination().ChannelMessageSeriesEnd(it.Channel(), propagation); m_blocked = false;
it.Next(); goto WasBlocked;
} }
m_it.Reset(channel);
while (!m_it.End())
{
WasBlocked:
if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation))
{
m_blocked = true;
return true;
}
m_it.Next();
}
return false; return false;
} }
byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned int &size) byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
{ {
ChannelRouteIterator it(*this, channel); m_it.Reset(channel);
if (!it.End()) if (!m_it.End())
{ {
BufferedTransformation &target = it.Destination(); BufferedTransformation &target = m_it.Destination();
it.Next(); m_it.Next();
if (it.End()) // there is only one target channel if (m_it.End()) // there is only one target channel
return target.ChannelCreatePutSpace(it.Channel(), size); return target.ChannelCreatePutSpace(m_it.Channel(), size);
} }
size = 0; size = 0;
return NULL; return NULL;
@ -215,10 +247,9 @@ byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned
unsigned int ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, unsigned int length, int messageEnd, bool blocking) unsigned int ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, unsigned int length, int messageEnd, bool blocking)
{ {
if (!blocking) ChannelRouteIterator it(*this);
throw BlockingInputOnly("ChannelSwitch"); it.Reset(channel);
ChannelRouteIterator it(*this, channel);
if (!it.End()) if (!it.End())
{ {
BufferedTransformation &target = it.Destination(); BufferedTransformation &target = it.Destination();
@ -227,8 +258,8 @@ unsigned int ChannelSwitch::ChannelPutModifiable2(const std::string &channel, by
if (it.End()) // there is only one target channel if (it.End()) // there is only one target channel
return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking);
} }
ChannelPut2(channel, inString, length, messageEnd, blocking);
return false; return ChannelPut2(channel, inString, length, messageEnd, blocking);
} }
void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination)

View File

@ -44,16 +44,48 @@ private:
}; };
#endif #endif
//! Route input to different and/or multiple channels based on channel ID class ChannelSwitchTypedefs
class ChannelSwitch : public Multichannel<Sink>
{ {
public: public:
ChannelSwitch() {} typedef std::pair<BufferedTransformation *, std::string> Route;
ChannelSwitch(BufferedTransformation &destination) typedef std::multimap<std::string, Route> RouteMap;
typedef std::pair<BufferedTransformation *, value_ptr<std::string> > DefaultRoute;
typedef std::list<DefaultRoute> DefaultRouteList;
typedef RouteMap::const_iterator MapIterator;
typedef DefaultRouteList::const_iterator ListIterator;
};
class ChannelSwitch;
class ChannelRouteIterator : public ChannelSwitchTypedefs
{
public:
ChannelSwitch& m_cs;
std::string m_channel;
bool m_useDefault;
MapIterator m_itMapCurrent, m_itMapEnd;
ListIterator m_itListCurrent, m_itListEnd;
ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {}
void Reset(const std::string &channel);
bool End() const;
void Next();
BufferedTransformation & Destination();
const std::string & Channel();
};
//! Route input to different and/or multiple channels based on channel ID
class ChannelSwitch : public Multichannel<Sink>, public ChannelSwitchTypedefs
{
public:
ChannelSwitch() : m_it(*this), m_blocked(false) {}
ChannelSwitch(BufferedTransformation &destination) : m_it(*this), m_blocked(false)
{ {
AddDefaultRoute(destination); AddDefaultRoute(destination);
} }
ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel) ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel) : m_it(*this), m_blocked(false)
{ {
AddDefaultRoute(destination, outChannel); AddDefaultRoute(destination, outChannel);
} }
@ -75,14 +107,12 @@ public:
void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel);
private: private:
typedef std::pair<BufferedTransformation *, std::string> Route;
typedef std::multimap<std::string, Route> RouteMap;
RouteMap m_routeMap; RouteMap m_routeMap;
typedef std::pair<BufferedTransformation *, value_ptr<std::string> > DefaultRoute;
typedef std::list<DefaultRoute> DefaultRouteList;
DefaultRouteList m_defaultRoutes; DefaultRouteList m_defaultRoutes;
ChannelRouteIterator m_it;
bool m_blocked;
friend class ChannelRouteIterator; friend class ChannelRouteIterator;
}; };

View File

@ -14,6 +14,7 @@ USEUNIT("bfinit.cpp");
USEUNIT("blowfish.cpp"); USEUNIT("blowfish.cpp");
USEUNIT("blumgold.cpp"); USEUNIT("blumgold.cpp");
USEUNIT("blumshub.cpp"); USEUNIT("blumshub.cpp");
USEUNIT("camellia.cpp");
USEUNIT("cast.cpp"); USEUNIT("cast.cpp");
USEUNIT("cast128s.cpp"); USEUNIT("cast128s.cpp");
USEUNIT("crc.cpp"); USEUNIT("crc.cpp");
@ -62,11 +63,11 @@ USEUNIT("ripemd.cpp");
USEUNIT("rng.cpp"); USEUNIT("rng.cpp");
USEUNIT("rsa.cpp"); USEUNIT("rsa.cpp");
USEUNIT("safer.cpp"); USEUNIT("safer.cpp");
USEUNIT("sapphire.cpp");
USEUNIT("seal.cpp"); USEUNIT("seal.cpp");
USEUNIT("secshare.cpp"); USEUNIT("secshare.cpp");
USEUNIT("secsplit.cpp"); USEUNIT("secsplit.cpp");
USEUNIT("sha.cpp"); USEUNIT("sha.cpp");
USEUNIT("shacal2.cpp");
USEUNIT("shark.cpp"); USEUNIT("shark.cpp");
USEUNIT("sharkbox.cpp"); USEUNIT("sharkbox.cpp");
USEUNIT("square.cpp"); USEUNIT("square.cpp");
@ -75,10 +76,12 @@ USEUNIT("tea.cpp");
USEUNIT("test.cpp"); USEUNIT("test.cpp");
USEUNIT("tiger.cpp"); USEUNIT("tiger.cpp");
USEUNIT("tigertab.cpp"); USEUNIT("tigertab.cpp");
USEUNIT("ttmac.cpp");
USEUNIT("validat1.cpp"); USEUNIT("validat1.cpp");
USEUNIT("validat2.cpp"); USEUNIT("validat2.cpp");
USEUNIT("validat3.cpp"); USEUNIT("validat3.cpp");
USEUNIT("wake.cpp"); USEUNIT("wake.cpp");
USEUNIT("whrlpool.cpp");
USEUNIT("zbits.cpp"); USEUNIT("zbits.cpp");
USEUNIT("zdeflate.cpp"); USEUNIT("zdeflate.cpp");
USEUNIT("zinflate.cpp"); USEUNIT("zinflate.cpp");

View File

@ -1,5 +1,5 @@
# Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 60000 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103 # TARGTYPE "Win32 (x86) Console Application" 0x0103
@ -74,7 +74,7 @@ PostBuild_Cmds=echo This configuration is used to build a static binary for FIPS
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c # ADD BASE CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c
# ADD CPP /nologo /G5 /Gz /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm200 /c # ADD CPP /nologo /G5 /Gz /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm300 /c
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@ -126,7 +126,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0 # PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c # ADD CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm300 /c
# ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
@ -157,6 +157,14 @@ SOURCE=.\3wayval.dat
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\anubisv.dat
# End Source File
# Begin Source File
SOURCE=.\camellia.dat
# End Source File
# Begin Source File
SOURCE=.\cast128v.dat SOURCE=.\cast128v.dat
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -225,6 +233,10 @@ SOURCE=.\ideaval.dat
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\khazadv.dat
# End Source File
# Begin Source File
SOURCE=.\luc1024.dat SOURCE=.\luc1024.dat
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -337,6 +349,14 @@ SOURCE=.\serpentv.dat
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\shacal1v.dat
# End Source File
# Begin Source File
SOURCE=.\shacal2v.dat
# End Source File
# Begin Source File
SOURCE=.\sharkval.dat SOURCE=.\sharkval.dat
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -1,5 +1,5 @@
# Microsoft Developer Studio Project File - Name="cryptlib" - Package Owner=<4> # Microsoft Developer Studio Project File - Name="cryptlib" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 60000 # Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT ** # ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104 # TARGTYPE "Win32 (x86) Static Library" 0x0104
@ -230,6 +230,10 @@ SOURCE=.\blumshub.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\camellia.cpp
# End Source File
# Begin Source File
SOURCE=.\cast.cpp SOURCE=.\cast.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -527,6 +531,10 @@ SOURCE=.\sha.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\shacal2.cpp
# End Source File
# Begin Source File
SOURCE=.\shark.cpp SOURCE=.\shark.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -579,6 +587,10 @@ SOURCE=.\trdlocal.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ttmac.cpp
# End Source File
# Begin Source File
SOURCE=.\twofish.cpp SOURCE=.\twofish.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -591,6 +603,10 @@ SOURCE=.\wake.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\whrlpool.cpp
# End Source File
# Begin Source File
SOURCE=.\winpipes.cpp SOURCE=.\winpipes.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -667,6 +683,10 @@ SOURCE=.\blumshub.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\camellia.h
# End Source File
# Begin Source File
SOURCE=.\cast.h SOURCE=.\cast.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -991,6 +1011,10 @@ SOURCE=.\sha.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\shacal2.h
# End Source File
# Begin Source File
SOURCE=.\shark.h SOURCE=.\shark.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -1035,6 +1059,10 @@ SOURCE=.\trunhash.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ttmac.h
# End Source File
# Begin Source File
SOURCE=.\twofish.h SOURCE=.\twofish.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -1047,6 +1075,10 @@ SOURCE=.\wake.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\whrlpool.h
# End Source File
# Begin Source File
SOURCE=.\winpipes.h SOURCE=.\winpipes.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -16,10 +16,12 @@ void Files_TestInstantiations()
void FileStore::StoreInitialize(const NameValuePairs &parameters) void FileStore::StoreInitialize(const NameValuePairs &parameters)
{ {
m_file.close();
m_file.clear();
const char *fileName; const char *fileName;
if (parameters.GetValue("InputFileName", fileName)) if (parameters.GetValue(Name::InputFileName(), fileName))
{ {
ios::openmode binary = parameters.GetValueWithDefault("InputBinaryMode", true) ? ios::binary : ios::openmode(0); ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0);
m_file.open(fileName, ios::in | binary); m_file.open(fileName, ios::in | binary);
if (!m_file) if (!m_file)
throw OpenErr(fileName); throw OpenErr(fileName);
@ -28,7 +30,7 @@ void FileStore::StoreInitialize(const NameValuePairs &parameters)
else else
{ {
m_stream = NULL; m_stream = NULL;
parameters.GetValue("InputStreamPointer", m_stream); parameters.GetValue(Name::InputStreamPointer(), m_stream);
} }
m_waiting = false; m_waiting = false;
} }
@ -137,12 +139,19 @@ unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned lo
return 0; return 0;
} }
unsigned long FileStore::Skip(unsigned long skipMax)
{
unsigned long oldPos = m_stream->tellg();
m_stream->seekg(skipMax, ios_base::cur);
return (unsigned long)m_stream->tellg() - oldPos;
}
void FileSink::IsolatedInitialize(const NameValuePairs &parameters) void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
{ {
const char *fileName; const char *fileName;
if (parameters.GetValue("OutputFileName", fileName)) if (parameters.GetValue(Name::OutputFileName(), fileName))
{ {
ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0); ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
m_file.open(fileName, ios::out | ios::trunc | binary); m_file.open(fileName, ios::out | ios::trunc | binary);
if (!m_file) if (!m_file)
throw OpenErr(fileName); throw OpenErr(fileName);
@ -151,7 +160,7 @@ void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
else else
{ {
m_stream = NULL; m_stream = NULL;
parameters.GetValue("OutputStreamPointer", m_stream); parameters.GetValue(Name::OutputStreamPointer(), m_stream);
} }
} }

14
files.h
View File

@ -3,6 +3,7 @@
#include "cryptlib.h" #include "cryptlib.h"
#include "filters.h" #include "filters.h"
#include "argnames.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -23,15 +24,16 @@ public:
FileStore() : m_stream(NULL) {} FileStore() : m_stream(NULL) {}
FileStore(std::istream &in) FileStore(std::istream &in)
{StoreInitialize(MakeParameters("InputStreamPointer", &in));} {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
FileStore(const char *filename) FileStore(const char *filename)
{StoreInitialize(MakeParameters("InputFileName", filename));} {StoreInitialize(MakeParameters(Name::InputFileName(), filename));}
std::istream* GetStream() {return m_stream;} std::istream* GetStream() {return m_stream;}
unsigned long MaxRetrievable() const; unsigned long MaxRetrievable() const;
unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
unsigned long Skip(unsigned long skipMax=ULONG_MAX);
private: private:
void StoreInitialize(const NameValuePairs &parameters); void StoreInitialize(const NameValuePairs &parameters);
@ -54,9 +56,9 @@ public:
FileSource(BufferedTransformation *attachment = NULL) FileSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {} : SourceTemplate<FileStore>(attachment) {}
FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL) FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputStreamPointer", &in));} : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));}
FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true)
: SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputFileName", filename)("InputBinaryMode", binary));} : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));}
std::istream* GetStream() {return m_store.GetStream();} std::istream* GetStream() {return m_store.GetStream();}
}; };
@ -75,9 +77,9 @@ public:
FileSink() : m_stream(NULL) {} FileSink() : m_stream(NULL) {}
FileSink(std::ostream &out) FileSink(std::ostream &out)
{IsolatedInitialize(MakeParameters("OutputStreamPointer", &out));} {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));}
FileSink(const char *filename, bool binary=true) FileSink(const char *filename, bool binary=true)
{IsolatedInitialize(MakeParameters("OutputFileName", filename)("OutputBinaryMode", binary));} {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)("OutputBinaryMode", binary));}
std::ostream* GetStream() {return m_stream;} std::ostream* GetStream() {return m_stream;}

View File

@ -381,10 +381,10 @@ void Redirector::ChannelInitialize(const std::string &channel, const NameValuePa
if (channel.empty()) if (channel.empty())
{ {
m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL); m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
m_passSignal = parameters.GetValueWithDefault("PassSignal", true); m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
} }
if (m_target && m_passSignal) if (m_target && GetPassSignals())
m_target->ChannelInitialize(channel, parameters, propagation); m_target->ChannelInitialize(channel, parameters, propagation);
} }

View File

@ -366,36 +366,55 @@ typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibili
class Redirector : public CustomSignalPropagation<Sink> class Redirector : public CustomSignalPropagation<Sink>
{ {
public: public:
Redirector() : m_target(NULL), m_passSignal(true) {} enum Behavior
Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {} {
DATA_ONLY = 0x00,
PASS_SIGNALS = 0x01,
PASS_WAIT_OBJECTS = 0x02,
PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
};
Redirector() : m_target(NULL), m_behavior(PASS_EVERYTHING) {}
Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING)
: m_target(&target), m_behavior(behavior) {}
void Redirect(BufferedTransformation &target) {m_target = &target;} void Redirect(BufferedTransformation &target) {m_target = &target;}
void StopRedirection() {m_target = NULL;} void StopRedirection() {m_target = NULL;}
bool GetPassSignal() const {return m_passSignal;}
void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} Behavior GetBehavior() {return (Behavior) m_behavior;}
void SetBehavior(Behavior behavior) {m_behavior=behavior;}
bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;}
void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~(word32) PASS_SIGNALS; }
bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;}
void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; }
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;} {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
void Initialize(const NameValuePairs &parameters, int propagation) void Initialize(const NameValuePairs &parameters, int propagation)
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);} {ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->Flush(hardFlush, propagation, blocking) : false;} {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
bool MessageSeriesEnd(int propagation=-1, bool blocking=true) bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->MessageSeriesEnd(propagation, blocking) : false;} {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1); void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking) unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;} {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking) unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking)
{return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking) : 0;} {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
{return m_target && m_passSignal ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
unsigned int GetMaxWaitObjectCount() const
{ return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; }
void GetWaitObjects(WaitObjectContainer &container)
{ if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container); }
private: private:
BufferedTransformation *m_target; BufferedTransformation *m_target;
bool m_passSignal; word32 m_behavior;
}; };
// Used By ProxyFilter // Used By ProxyFilter

877
fipsalgt.cpp Normal file
View File

@ -0,0 +1,877 @@
// fipsalgt.cpp - written and placed in the public domain by Wei Dai
// This file implements the various algorithm tests needed to pass FIPS 140 validation.
// They're preserved here (commented out) in case Crypto++ needs to be revalidated.
/*
class LineBreakParser : public AutoSignaling<Bufferless<Filter> >
{
public:
LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n')
: AutoSignaling<Bufferless<Filter> >(attachment), m_lineEnd(lineEnd) {}
unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
if (!blocking)
throw BlockingInputOnly("LineBreakParser");
unsigned int i, last = 0;
for (i=0; i<length; i++)
{
if (begin[i] == m_lineEnd)
{
AttachedTransformation()->Put2(begin+last, i-last, GetAutoSignalPropagation(), blocking);
last = i+1;
}
}
if (last != i)
AttachedTransformation()->Put2(begin+last, i-last, 0, blocking);
if (messageEnd && GetAutoSignalPropagation())
{
AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking);
AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking);
}
return 0;
}
private:
byte m_lineEnd;
};
class TestDataParser : public Unflushable<FilterWithInputQueue>
{
public:
enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT};
TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment)
: Unflushable<FilterWithInputQueue>(attachment)
, m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize)
, m_firstLine(true), m_blankLineTransition(0)
{
m_nameToType["COUNT"] = COUNT;
m_nameToType["KEY"] = KEY_T;
m_nameToType["KEYs"] = KEY_T;
m_nameToType["key"] = KEY_T;
m_nameToType["IV"] = IV;
m_nameToType["IV1"] = IV;
m_nameToType["CV"] = IV;
m_nameToType["CV1"] = IV;
m_nameToType["IB"] = IV;
m_nameToType["TEXT"] = INPUT;
m_nameToType["RESULT"] = OUTPUT;
SetEncrypt(encrypt);
if (m_algorithm == "DSS")
{
if (m_test == "prime")
m_trigger = "Prime";
else if (m_test == "pqg")
m_trigger = "N";
else if (m_test == "xy")
m_trigger = "G";
else if (m_test == "gensig")
m_trigger = "Msg";
else if (m_test == "versig")
m_trigger = "Sig";
else if (m_test == "verpqg")
m_trigger = "c";
}
}
void SetEncrypt(bool encrypt)
{
m_encrypt = encrypt;
if (encrypt)
{
m_nameToType["PLAINTEXT"] = INPUT;
m_nameToType["CIPHERTEXT"] = OUTPUT;
m_nameToType["PT"] = INPUT;
m_nameToType["CT"] = OUTPUT;
}
else
{
m_nameToType["PLAINTEXT"] = OUTPUT;
m_nameToType["CIPHERTEXT"] = INPUT;
m_nameToType["PT"] = OUTPUT;
m_nameToType["CT"] = INPUT;
}
}
protected:
void OutputData(std::string &output, const std::string &key, const std::string &data)
{
output += key;
output += "= ";
output += data;
output += "\n";
}
void OutputData(std::string &output, const std::string &key, int data)
{
OutputData(output, key, IntToString(data));
}
void OutputData(std::string &output, const std::string &key, const SecByteBlock &data)
{
output += key;
output += "= ";
HexEncoder(new StringSink(output), false).Put(data, data.size());
output += "\n";
}
void OutputData(std::string &output, const std::string &key, const Integer &data)
{
SecByteBlock s(data.MinEncodedSize());
data.Encode(s, s.size());
OutputData(output, key, s);
}
void OutputData(std::string &output, DataType t, const std::string &data)
{
if (m_algorithm == "SKIPJACK")
{
if (m_test == "KAT")
{
if (t == OUTPUT)
output = m_line + data + "\n";
}
else
{
if (t != COUNT)
{
output += m_typeToName[t];
output += "=";
}
output += data;
output += t == OUTPUT ? "\n" : " ";
}
}
else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty())
{
output += "KEY1 = ";
output += data.substr(0, 16);
output += "\nKEY2 = ";
output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16);
output += "\nKEY3 = ";
output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16);
output += "\n";
}
else
{
output += m_typeToName[t];
output += " = ";
output += data;
output += "\n";
}
}
void OutputData(std::string &output, DataType t, int i)
{
OutputData(output, t, IntToString(i));
}
void OutputData(std::string &output, DataType t, const SecByteBlock &data)
{
std::string hexData;
StringSource(data, true, new HexEncoder(new StringSink(hexData), false));
OutputData(output, t, hexData);
}
void OutputGivenData(std::string &output, DataType t, bool optional = false)
{
if (m_data.find(m_typeToName[t]) == m_data.end())
{
if (optional)
return;
throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]);
}
OutputData(output, t, m_data[m_typeToName[t]]);
}
template <class T>
BlockCipher * NewBT(T *)
{
if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC"))
return new typename T::Decryption;
else
return new typename T::Encryption;
}
template <class T>
SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv)
{
if (!m_encrypt)
return new typename T::Decryption(bt, iv, m_feedbackSize/8);
else
return new typename T::Encryption(bt, iv, m_feedbackSize/8);
}
static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y)
{
assert(x.size() == y.size());
z.resize(x.size());
xorbuf(z, x, y, x.size());
}
SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text)
{
unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
int keySize = key.size(), blockSize = text[0].size();
SecByteBlock x(keySize);
for (int k=0; k<keySize;)
{
int pos = innerCount * blockSize - keySize + k;
memcpy(x + k, text[pos / blockSize] + pos % blockSize, blockSize - pos % blockSize);
k += blockSize - pos % blockSize;
}
if (m_algorithm == "TDES" || m_algorithm == "DES")
{
for (int i=0; i<keySize; i+=8)
{
xorbuf(key+i, x+keySize-8-i, 8);
DES::CorrectKeyParityBits(key+i);
}
}
else
xorbuf(key, x, keySize);
return key;
}
static inline void AssignLeftMostBits(SecByteBlock &z, const SecByteBlock &x, unsigned int K)
{
z.Assign(x, K/8);
}
virtual void DoTest()
{
std::string output;
if (m_algorithm == "DSS")
{
if (m_test == "sha")
{
assert(m_compactString.size() >= 2);
assert(m_compactString[0] == m_compactString.size()-2);
bool b = !!m_compactString[1];
Integer m;
unsigned int bitLength = 0;
for (unsigned int j = 2; j < m_compactString.size(); j++)
{
m <<= m_compactString[j];
for (unsigned int k = 0; k < m_compactString[j]; k++)
m.SetBit(k, b);
bitLength += m_compactString[j];
b = !b;
}
m_compactString.clear();
assert(bitLength % 8 == 0);
SecByteBlock message(bitLength / 8);
m.Encode(message, message.size());
SHA sha;
if (m_bracketString == "SHS Type 3 Strings")
{
SecByteBlock m1;
for (int j = 0; j < 100; j++)
{
for (word32 i = 1; i <= 50000; i++)
{
m1.resize(message.size() + j/4 + 3 + 4);
memcpy(m1, message, message.size());
memset(m1 + message.size(), 0, j/4 + 3);
PutWord(false, BIG_ENDIAN_ORDER, m1 + m1.size() - 4, i);
message.resize(sha.DigestSize());
sha.CalculateDigest(message, m1, m1.size());
}
StringSource(message, message.size(), true, new HexEncoder(new StringSink(output)));
output += " ^\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
}
else
{
StringSource(message, message.size(), true, new HashFilter(sha, new HexEncoder(new StringSink(output))));
output += " ^\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
}
}
else if (m_test == "prime")
{
Integer p((m_data["Prime"] + "h").c_str());
OutputData(output, "result", VerifyPrime(m_rng, p, 2) ? "P" : "F");
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
else if (m_test == "pqg")
{
int n = atol(m_data["N"].c_str());
for (int i=0; i<n; i++)
{
Integer p, q, h, g;
int counter;
SecByteBlock seed(SHA::DIGESTSIZE);
do
{
m_rng.GenerateBlock(seed, seed.size());
}
while (!DSA::GeneratePrimes(seed, seed.size()*8, counter, p, 1024, q));
h.Randomize(m_rng, 2, p-2);
g = a_exp_b_mod_c(h, (p-1)/q, p);
OutputData(output, "P", p);
OutputData(output, "Q", q);
OutputData(output, "G", g);
OutputData(output, "Seed", seed);
OutputData(output, "H", h);
OutputData(output, "c", counter);
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
}
else if (m_test == "xy")
{
Integer p((m_data["P"] + "h").c_str());
Integer q((m_data["Q"] + "h").c_str());
Integer g((m_data["G"] + "h").c_str());
for (int i=0; i<10; i++)
{
DSA::Signer priv(m_rng, p, q, g);
DSA::Verifier pub(priv);
OutputData(output, "X", priv.GetKey().GetPrivateExponent());
OutputData(output, "Y", pub.GetKey().GetPublicElement());
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
}
else if (m_test == "gensig")
{
Integer p((m_data["P"] + "h").c_str());
Integer q((m_data["Q"] + "h").c_str());
Integer g((m_data["G"] + "h").c_str());
Integer x((m_data["X"] + "h").c_str());
DSA::Signer signer(p, q, g, x);
SecByteBlock sig(signer.SignatureLength());
StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size()))));
OutputData(output, "Sig", sig);
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
else if (m_test == "versig")
{
Integer p((m_data["P"] + "h").c_str());
Integer q((m_data["Q"] + "h").c_str());
Integer g((m_data["G"] + "h").c_str());
Integer y((m_data["Y"] + "h").c_str());
DSA::Verifier verifier(p, q, g, y);
HexDecoder filter(new SignatureVerificationFilter(verifier));
StringSource(m_data["Sig"], true, new Redirector(filter, false));
StringSource(m_data["Msg"], true, new Redirector(filter, false));
filter.MessageEnd();
byte b;
filter.Get(b);
OutputData(output, "result", b ? "P" : "F");
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
else if (m_test == "verpqg")
{
Integer p((m_data["P"] + "h").c_str());
Integer q((m_data["Q"] + "h").c_str());
Integer g((m_data["G"] + "h").c_str());
Integer h((m_data["H"] + "h").c_str());
int c = atol(m_data["c"].c_str());
SecByteBlock seed(m_data["Seed"].size()/2);
StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size())));
Integer p1, q1;
bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true);
result = result && (p1 == p && q1 == q);
result = result && g == a_exp_b_mod_c(h, (p-1)/q, p);
OutputData(output, "result", result ? "P" : "F");
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
return;
}
SecByteBlock &key = m_data2[KEY_T];
if (m_algorithm == "TDES")
{
if (!m_data["KEY1"].empty())
{
const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]};
key.resize(24);
HexDecoder hexDec(new ArraySink(key, key.size()));
for (int i=0; i<3; i++)
hexDec.Put((byte *)keys[i].data(), keys[i].size());
if (keys[0] == keys[2])
{
if (keys[0] == keys[1])
key.resize(8);
else
key.resize(16);
}
else
key.resize(24);
}
}
member_ptr<BlockCipher> pBT;
if (m_algorithm == "DES")
pBT.reset(NewBT((DES*)0));
else if (m_algorithm == "TDES")
{
if (key.size() == 8)
pBT.reset(NewBT((DES*)0));
else if (key.size() == 16)
pBT.reset(NewBT((DES_EDE2*)0));
else
pBT.reset(NewBT((DES_EDE3*)0));
}
else if (m_algorithm == "SKIPJACK")
pBT.reset(NewBT((SKIPJACK*)0));
else if (m_algorithm == "AES")
pBT.reset(NewBT((AES*)0));
else
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm);
if (!pBT->IsValidKeyLength(key.size()))
key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct
pBT->SetKey(key.data(), key.size());
SecByteBlock &iv = m_data2[IV];
if (iv.empty())
iv.CleanNew(pBT->BlockSize());
member_ptr<SymmetricCipher> pCipher;
unsigned int K = m_feedbackSize;
if (m_mode == "ECB")
pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv));
else if (m_mode == "CBC")
pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv));
else if (m_mode == "CFB")
pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv));
else if (m_mode == "OFB")
pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv));
else
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
bool encrypt = m_encrypt;
if (m_test == "MONTE")
{
SecByteBlock KEY[401];
KEY[0] = key;
int keySize = key.size();
int blockSize = pBT->BlockSize();
SecByteBlock IB[10001], OB[10001], PT[10001], CT[10001], RESULT[10001], TXT[10001], CV[10001];
PT[0] = GetData("PLAINTEXT");
CT[0] = GetData("CIPHERTEXT");
CV[0] = IB[0] = iv;
TXT[0] = GetData("TEXT");
unsigned int outerCount = (m_algorithm == "AES") ? 100 : 400;
unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000;
for (int i=0; i<outerCount; i++)
{
pBT->SetKey(KEY[i], keySize);
for (int j=0; j<innerCount; j++)
{
if (m_mode == "ECB")
{
if (encrypt)
{
IB[j] = PT[j];
CT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], CT[j]);
PT[j+1] = CT[j];
}
else
{
IB[j] = CT[j];
PT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], PT[j]);
CT[j+1] = PT[j];
}
}
else if (m_mode == "OFB")
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
Xor(RESULT[j], OB[j], TXT[j]);
TXT[j+1] = IB[j];
IB[j+1] = OB[j];
}
else if (m_mode == "CBC")
{
if (encrypt)
{
Xor(IB[j], PT[j], CV[j]);
CT[j].resize(blockSize);
pBT->ProcessBlock(IB[j], CT[j]);
PT[j+1] = CV[j];
CV[j+1] = CT[j];
}
else
{
IB[j] = CT[j];
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
Xor(PT[j], OB[j], CV[j]);
CV[j+1] = CT[j];
CT[j+1] = PT[j];
}
}
else if (m_mode == "CFB")
{
if (encrypt)
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
AssignLeftMostBits(CT[j], OB[j], K);
Xor(CT[j], CT[j], PT[j]);
AssignLeftMostBits(PT[j+1], IB[j], K);
IB[j+1].resize(blockSize);
memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
}
else
{
OB[j].resize(blockSize);
pBT->ProcessBlock(IB[j], OB[j]);
AssignLeftMostBits(PT[j], OB[j], K);
Xor(PT[j], PT[j], CT[j]);
IB[j+1].resize(blockSize);
memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8);
memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8);
AssignLeftMostBits(CT[j+1], OB[j], K);
}
}
else
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode);
}
OutputData(output, COUNT, i);
OutputData(output, KEY_T, KEY[i]);
if (m_mode == "CBC")
OutputData(output, IV, CV[0]);
if (m_mode == "OFB" || m_mode == "CFB")
OutputData(output, IV, IB[0]);
if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB")
{
if (encrypt)
{
OutputData(output, INPUT, PT[0]);
OutputData(output, OUTPUT, CT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], CT);
}
else
{
OutputData(output, INPUT, CT[0]);
OutputData(output, OUTPUT, PT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], PT);
}
PT[0] = PT[innerCount];
IB[0] = IB[innerCount];
CV[0] = CV[innerCount];
CT[0] = CT[innerCount];
}
else if (m_mode == "OFB")
{
OutputData(output, INPUT, TXT[0]);
OutputData(output, OUTPUT, RESULT[innerCount-1]);
KEY[i+1] = UpdateKey(KEY[i], RESULT);
Xor(TXT[0], TXT[0], IB[innerCount-1]);
IB[0] = OB[innerCount-1];
}
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
}
}
else if (m_test == "MCT")
{
SecByteBlock KEY[101];
KEY[0] = key;
int keySize = key.size();
int blockSize = pBT->BlockSize();
SecByteBlock ivs[101], inputs[1001], outputs[1001];
ivs[0] = iv;
inputs[0] = m_data2[INPUT];
for (int i=0; i<100; i++)
{
pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8));
for (int j=0; j<1000; j++)
{
outputs[j] = inputs[j];
pCipher->ProcessString(outputs[j], outputs[j].size());
if (K==8 && m_mode == "CFB")
{
if (j<16)
inputs[j+1].Assign(ivs[i]+j, 1);
else
inputs[j+1] = outputs[j-16];
}
else if (m_mode == "ECB")
inputs[j+1] = outputs[j];
else if (j == 0)
inputs[j+1] = ivs[i];
else
inputs[j+1] = outputs[j-1];
}
OutputData(output, KEY_T, KEY[i]);
if (m_mode != "ECB")
OutputData(output, IV, ivs[i]);
OutputData(output, INPUT, inputs[0]);
OutputData(output, OUTPUT, outputs[999]);
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
output.resize(0);
KEY[i+1] = UpdateKey(KEY[i], outputs);
ivs[i+1].CleanNew(pCipher->IVSize());
ivs[i+1] = UpdateKey(ivs[i+1], outputs);
if (K==8 && m_mode == "CFB")
inputs[0] = outputs[999-16];
else if (m_mode == "ECB")
inputs[0] = outputs[999];
else
inputs[0] = outputs[998];
}
}
else
{
assert(m_test == "KAT");
SecByteBlock &input = m_data2[INPUT];
SecByteBlock result(input.size());
member_ptr<Filter> pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING));
StringSource(input.data(), input.size(), true, pFilter.release());
OutputGivenData(output, COUNT, true);
OutputData(output, KEY_T, key);
OutputGivenData(output, IV, true);
OutputGivenData(output, INPUT);
OutputData(output, OUTPUT, result);
output += "\n";
AttachedTransformation()->Put((byte *)output.data(), output.size());
}
}
std::vector<std::string> Tokenize(const std::string &line)
{
std::vector<std::string> result;
std::string s;
for (int i=0; i<line.size(); i++)
{
if (isalnum(line[i]) || line[i] == '^')
s += line[i];
else if (!s.empty())
{
result.push_back(s);
s = "";
}
if (line[i] == '=')
result.push_back("=");
}
result.push_back(s);
return result;
}
bool IsolatedMessageEnd(bool blocking)
{
if (!blocking)
throw BlockingInputOnly("TestDataParser");
m_line.resize(0);
m_inQueue.TransferTo(StringSink(m_line).Ref());
if (m_line[0] == '#')
return false;
bool copyLine = false;
if (m_line[0] == '[')
{
m_bracketString = m_line.substr(1, m_line.size()-2);
if (m_bracketString == "ENCRYPT")
SetEncrypt(true);
if (m_bracketString == "DECRYPT")
SetEncrypt(false);
copyLine = true;
}
if (m_line.substr(0, 2) == "H>")
{
assert(m_test == "sha");
m_bracketString = m_line.substr(2, m_line.size()-4);
m_line = m_line.substr(0, 13) + "Hashes<H";
copyLine = true;
}
if (m_line == "D>")
copyLine = true;
if (m_line == "<D")
{
m_line += "\n";
copyLine = true;
}
if (copyLine)
{
m_line += '\n';
AttachedTransformation()->Put((byte *)m_line.data(), m_line.size(), blocking);
return false;
}
std::vector<std::string> tokens = Tokenize(m_line);
if (m_algorithm == "DSS" && m_test == "sha")
{
for (int i = 0; i < tokens.size(); i++)
{
if (tokens[i] == "^")
DoTest();
else if (tokens[i] != "")
m_compactString.push_back(atol(tokens[i].c_str()));
}
}
else
{
if (!m_line.empty() && m_algorithm == "DSS" && m_test != "pqg")
{
std::string output = m_line + '\n';
AttachedTransformation()->Put((byte *)output.data(), output.size());
}
for (int i = 0; i < tokens.size(); i++)
{
if (m_firstLine && m_algorithm != "DSS")
{
if (tokens[i] == "Encrypt" || tokens[i] == "OFB")
SetEncrypt(true);
else if (tokens[i] == "Decrypt")
SetEncrypt(false);
else if (tokens[i] == "Modes")
m_test = "MONTE";
}
else
{
if (tokens[i] != "=")
continue;
if (i == 0)
throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line);
const std::string &key = tokens[i-1];
std::string &data = m_data[key];
data = tokens[i+1];
DataType t = m_nameToType[key];
m_typeToName[t] = key;
SecByteBlock data2(data.size() / 2);
StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size())));
m_data2[t] = data2;
if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty()))
DoTest();
}
}
}
m_firstLine = false;
return false;
}
inline const SecByteBlock & GetData(const std::string &key)
{
return m_data2[m_nameToType[key]];
}
std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger;
unsigned int m_feedbackSize, m_blankLineTransition;
bool m_encrypt, m_firstLine;
typedef std::map<std::string, DataType> NameToTypeMap;
NameToTypeMap m_nameToType;
typedef std::map<DataType, std::string> TypeToNameMap;
TypeToNameMap m_typeToName;
typedef std::map<std::string, std::string> Map;
Map m_data; // raw data
typedef std::map<DataType, SecByteBlock> Map2;
Map2 m_data2;
AutoSeededX917RNG<DES_EDE3> m_rng;
std::vector<unsigned int> m_compactString;
};
*/
/*
int main (int argc, char **argv)
{
std::string algorithm = argv[1];
std::string pathname = argv[2];
i = pathname.find_last_of("\\/");
std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1);
std::string mode;
if (filename[0] == 'S' || filename[0] == 'T')
mode = filename.substr(1, 3);
else
mode = filename.substr(0, 3);
for (i = 0; i<mode.size(); i++)
mode[i] = toupper(mode[i]);
unsigned int feedbackSize = mode == "CFB" ? atoi(filename.substr(filename.find_first_of("0123456789")).c_str()) : 0;
std::string test;
if (algorithm == "DSS")
test = filename.substr(0, filename.size() - 4);
else if (filename.find("Monte") != std::string::npos)
test = "MONTE";
else if (filename.find("MCT") != std::string::npos)
test = "MCT";
else
test = "KAT";
bool encrypt = (filename.find("vrct") == std::string::npos);
BufferedTransformation *pSink = NULL;
if (argc > 3)
{
std::string outDir = argv[3];
if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/')
outDir += '/';
std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp";
pSink = new FileSink(outPathname.c_str(), false);
}
else
pSink = new FileSink(cout);
FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false);
}
*/

View File

@ -42,6 +42,7 @@ void X917RNG_KnownAnswerTest(
unsigned int deterministicTimeVector, unsigned int deterministicTimeVector,
CIPHER *dummy = NULL) CIPHER *dummy = NULL)
{ {
#ifdef OS_RNG_AVAILABLE
std::string decodedKey, decodedSeed; std::string decodedKey, decodedSeed;
StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); StringSource(key, true, new HexDecoder(new StringSink(decodedKey)));
StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed))); StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed)));
@ -49,6 +50,9 @@ void X917RNG_KnownAnswerTest(
AutoSeededX917RNG<CIPHER> rng; AutoSeededX917RNG<CIPHER> rng;
rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), deterministicTimeVector); rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), deterministicTimeVector);
KnownAnswerTest(rng, output); KnownAnswerTest(rng, output);
#else
throw 0;
#endif
} }
void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext) void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext)
@ -128,19 +132,25 @@ void MAC_KnownAnswerTest(const char *key, const char *message, const char *diges
template <class SCHEME> template <class SCHEME>
void SignatureKnownAnswerTest(const char *key, const char *message, const char *signature, SCHEME *dummy = NULL) void SignatureKnownAnswerTest(const char *key, const char *message, const char *signature, SCHEME *dummy = NULL)
{ {
#ifdef OS_RNG_AVAILABLE
AutoSeededX917RNG<DES_EDE3> rng;
#else
RandomNumberGenerator &rng = NullRNG();
#endif
typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref()); typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref());
typename SCHEME::Verifier verifier(signer); typename SCHEME::Verifier verifier(signer);
EqualityComparisonFilter comparison; EqualityComparisonFilter comparison;
StringSource(message, true, new SignerFilter(NullRNG(), signer, new ChannelSwitch(comparison, "0"))); StringSource(message, true, new SignerFilter(rng, signer, new ChannelSwitch(comparison, "0")));
StringSource(signature, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); StringSource(signature, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
comparison.ChannelMessageSeriesEnd("0"); comparison.ChannelMessageSeriesEnd("0");
comparison.ChannelMessageSeriesEnd("1"); comparison.ChannelMessageSeriesEnd("1");
VerifierFilter verifierFilter(verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN | VerifierFilter::THROW_EXCEPTION); VerifierFilter verifierFilter(verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN | VerifierFilter::THROW_EXCEPTION);
StringSource(signature, true, new HexDecoder(new Redirector(verifierFilter, false))); StringSource(signature, true, new HexDecoder(new Redirector(verifierFilter, Redirector::DATA_ONLY)));
StringSource(message, true, new Redirector(verifierFilter)); StringSource(message, true, new Redirector(verifierFilter));
} }
@ -222,7 +232,33 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha
SHA1 sha; SHA1 sha;
HashVerifier verifier(sha); HashVerifier verifier(sha);
verifier.Put(expectedModuleSha1Digest, sha.DigestSize()); verifier.Put(expectedModuleSha1Digest, sha.DigestSize());
FileStore(moduleFilename).TransferAllTo(verifier); FileStore file(moduleFilename);
#ifdef CRYPTOPP_WIN32_AVAILABLE
// try to hash from memory first
HMODULE h = GetModuleHandle(moduleFilename);
IMAGE_DOS_HEADER *ph = (IMAGE_DOS_HEADER *)h;
IMAGE_NT_HEADERS *phnt = (IMAGE_NT_HEADERS *)((byte *)h + ph->e_lfanew);
IMAGE_SECTION_HEADER *phs = (IMAGE_SECTION_HEADER *)((byte *)&phnt->OptionalHeader + phnt->FileHeader.SizeOfOptionalHeader);
DWORD SectionSize = STDMIN(phs->SizeOfRawData, phs->Misc.VirtualSize);
file.TransferTo(verifier, phs->PointerToRawData);
verifier.Put((const byte *)h + phs->VirtualAddress, SectionSize);
file.Skip(SectionSize);
#endif
file.TransferAllTo(verifier);
#ifdef CRYPTOPP_WIN32_AVAILABLE
// if that fails (could be caused by debug breakpoints or DLL base relocation modifying image in memory),
// hash from disk instead
if (!verifier.GetLastResult())
{
verifier.Put(expectedModuleSha1Digest, sha.DigestSize());
file.Initialize(MakeParameters(Name::InputFileName(), moduleFilename));
file.TransferAllTo(verifier);
}
#endif
if (!verifier.GetLastResult()) if (!verifier.GetLastResult())
{ {
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE

13
md2.cpp
View File

@ -80,8 +80,17 @@ void MD2::Update(const byte *buf, unsigned int len)
t=0; t=0;
for(i=0; i<18; i++) for(i=0; i<18; i++)
{ {
for(j=0; j<48; j++) for(j=0; j<48; j+=8)
t=m_X[j]^=S[t]; {
t=m_X[j+0]^=S[t];
t=m_X[j+1]^=S[t];
t=m_X[j+2]^=S[t];
t=m_X[j+3]^=S[t];
t=m_X[j+4]^=S[t];
t=m_X[j+5]^=S[t];
t=m_X[j+6]^=S[t];
t=m_X[j+7]^=S[t];
}
t=(t+i) & 0xFF; t=(t+i) & 0xFF;
} }
} }

65
misc.h
View File

@ -480,6 +480,31 @@ inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, wo
: word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24); : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
} }
#ifdef WORD64_AVAILABLE
inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word64*)
{
return (order == BIG_ENDIAN_ORDER)
?
(word64(block[7]) |
(word64(block[6]) << 8) |
(word64(block[5]) << 16) |
(word64(block[4]) << 24) |
(word64(block[3]) << 32) |
(word64(block[2]) << 40) |
(word64(block[1]) << 48) |
(word64(block[0]) << 56))
:
(word64(block[0]) |
(word64(block[1]) << 8) |
(word64(block[2]) << 16) |
(word64(block[3]) << 24) |
(word64(block[4]) << 32) |
(word64(block[5]) << 40) |
(word64(block[6]) << 48) |
(word64(block[7]) << 56));
}
#endif
template <class T> template <class T>
inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL) inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
{ {
@ -537,6 +562,46 @@ inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const b
} }
} }
#ifdef WORD64_AVAILABLE
inline void UnalignedPutWord(ByteOrder order, byte *block, word64 value, const byte *xorBlock = NULL)
{
if (order == BIG_ENDIAN_ORDER)
{
block[0] = GETBYTE(value, 7);
block[1] = GETBYTE(value, 6);
block[2] = GETBYTE(value, 5);
block[3] = GETBYTE(value, 4);
block[4] = GETBYTE(value, 3);
block[5] = GETBYTE(value, 2);
block[6] = GETBYTE(value, 1);
block[7] = GETBYTE(value, 0);
}
else
{
block[0] = GETBYTE(value, 0);
block[1] = GETBYTE(value, 1);
block[2] = GETBYTE(value, 2);
block[3] = GETBYTE(value, 3);
block[4] = GETBYTE(value, 4);
block[5] = GETBYTE(value, 5);
block[6] = GETBYTE(value, 6);
block[7] = GETBYTE(value, 7);
}
if (xorBlock)
{
block[0] ^= xorBlock[0];
block[1] ^= xorBlock[1];
block[2] ^= xorBlock[2];
block[3] ^= xorBlock[3];
block[4] ^= xorBlock[4];
block[5] ^= xorBlock[5];
block[6] ^= xorBlock[6];
block[7] ^= xorBlock[7];
}
}
#endif
template <class T> template <class T>
inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block) inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
{ {

View File

@ -1,5 +1,6 @@
#include "factory.h" #include "factory.h"
#include "modes.h"
#include "dh.h" #include "dh.h"
#include "esign.h" #include "esign.h"
#include "md2.h" #include "md2.h"
@ -10,6 +11,10 @@
#include "ripemd.h" #include "ripemd.h"
#include "dsa.h" #include "dsa.h"
#include "seal.h" #include "seal.h"
#include "whrlpool.h"
#include "ttmac.h"
#include "camellia.h"
#include "shacal2.h"
USING_NAMESPACE(CryptoPP) USING_NAMESPACE(CryptoPP)
@ -20,9 +25,11 @@ void RegisterFactories()
RegisterDefaultFactoryFor<HashTransformation, SHA256>("SHA-256"); RegisterDefaultFactoryFor<HashTransformation, SHA256>("SHA-256");
RegisterDefaultFactoryFor<HashTransformation, SHA384>("SHA-384"); RegisterDefaultFactoryFor<HashTransformation, SHA384>("SHA-384");
RegisterDefaultFactoryFor<HashTransformation, SHA512>("SHA-512"); RegisterDefaultFactoryFor<HashTransformation, SHA512>("SHA-512");
RegisterDefaultFactoryFor<HashTransformation, Whirlpool>("Whirlpool");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)"); RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)"); RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)"); RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)");
RegisterDefaultFactoryFor<MessageAuthenticationCode, TTMAC >("Two-Track-MAC");
RegisterAsymmetricCipherDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)"); RegisterAsymmetricCipherDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)");
RegisterAsymmetricCipherDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); RegisterAsymmetricCipherDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)");
RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)"); RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)");
@ -34,4 +41,6 @@ void RegisterFactories()
RegisterSignatureSchemeDefaultFactories<RWSS<P1363_EMSA2, SHA1> >("RW/EMSA2(SHA-1)"); RegisterSignatureSchemeDefaultFactories<RWSS<P1363_EMSA2, SHA1> >("RW/EMSA2(SHA-1)");
RegisterSignatureSchemeDefaultFactories<RSASS<PSS, SHA1> >("RSA/PSS-MGF1(SHA-1)"); RegisterSignatureSchemeDefaultFactories<RSASS<PSS, SHA1> >("RSA/PSS-MGF1(SHA-1)");
RegisterSymmetricCipherDefaultFactories<SEAL<> >("SEAL-3.0-BE"); RegisterSymmetricCipherDefaultFactories<SEAL<> >("SEAL-3.0-BE");
RegisterSymmetricCipherDefaultFactories<ECB_Mode<Camellia> >("Camellia(ECB)");
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SHACAL2> >("SHACAL-2(ECB)");
} }

View File

@ -1,4 +1,7 @@
// ripemd.cpp - written and placed in the public domain by Wei Dai // ripemd.cpp
// RIPEMD-160 written and placed in the public domain by Wei Dai
// RIPEMD-320, RIPEMD-128, RIPEMD-256 written by Kevin Springle
// and also placed in the public domain
#include "pch.h" #include "pch.h"
#include "ripemd.h" #include "ripemd.h"
@ -6,22 +9,6 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
void RIPEMD160::Init()
{
m_digest[0] = 0x67452301L;
m_digest[1] = 0xefcdab89L;
m_digest[2] = 0x98badcfeL;
m_digest[3] = 0x10325476L;
m_digest[4] = 0xc3d2e1f0L;
}
void RIPEMD160::Transform (word32 *digest, const word32 *X)
{
#define Subround(f, a, b, c, d, e, x, s, k) \
a += f(b, c, d) + x + k;\
a = rotlFixed((word32)a, s) + e;\
c = rotlFixed((word32)c, 10U)
#define F(x, y, z) (x ^ y ^ z) #define F(x, y, z) (x ^ y ^ z)
#define G(x, y, z) (z ^ (x & (y^z))) #define G(x, y, z) (z ^ (x & (y^z)))
#define H(x, y, z) (z ^ (x | ~y)) #define H(x, y, z) (z ^ (x | ~y))
@ -39,6 +26,25 @@ void RIPEMD160::Transform (word32 *digest, const word32 *X)
#define k8 0x7a6d76e9UL #define k8 0x7a6d76e9UL
#define k9 0 #define k9 0
// *************************************************************
// for 160 and 320
#define Subround(f, a, b, c, d, e, x, s, k) \
a += f(b, c, d) + x + k;\
a = rotlFixed((word32)a, s) + e;\
c = rotlFixed((word32)c, 10U)
void RIPEMD160::Init()
{
m_digest[0] = 0x67452301L;
m_digest[1] = 0xefcdab89L;
m_digest[2] = 0x98badcfeL;
m_digest[3] = 0x10325476L;
m_digest[4] = 0xc3d2e1f0L;
}
void RIPEMD160::Transform (word32 *digest, const word32 *X)
{
unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
a1 = a2 = digest[0]; a1 = a2 = digest[0];
b1 = b2 = digest[1]; b1 = b2 = digest[1];
@ -224,4 +230,574 @@ void RIPEMD160::Transform (word32 *digest, const word32 *X)
digest[0] = c1; digest[0] = c1;
} }
// *************************************************************
void RIPEMD320::Init()
{
m_digest[0] = 0x67452301L;
m_digest[1] = 0xefcdab89L;
m_digest[2] = 0x98badcfeL;
m_digest[3] = 0x10325476L;
m_digest[4] = 0xc3d2e1f0L;
m_digest[5] = 0x76543210L;
m_digest[6] = 0xfedcba98L;
m_digest[7] = 0x89abcdefL;
m_digest[8] = 0x01234567L;
m_digest[9] = 0x3c2d1e0fL;
}
void RIPEMD320::Transform (word32 *digest, const word32 *X)
{
unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2, t;
a1 = digest[0];
b1 = digest[1];
c1 = digest[2];
d1 = digest[3];
e1 = digest[4];
a2 = digest[5];
b2 = digest[6];
c2 = digest[7];
d2 = digest[8];
e2 = digest[9];
Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0);
Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0);
Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0);
Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0);
Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0);
Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0);
Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0);
Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0);
Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0);
Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0);
Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0);
Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0);
Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0);
Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0);
Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0);
Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0);
Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5);
Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5);
Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5);
Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5);
Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5);
Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5);
Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5);
Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5);
Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5);
Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5);
Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5);
Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5);
Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5);
Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5);
Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5);
Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5);
t = a1; a1 = a2; a2 = t;
Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1);
Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1);
Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1);
Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1);
Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1);
Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1);
Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1);
Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1);
Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1);
Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1);
Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1);
Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1);
Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1);
Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1);
Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1);
Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1);
Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6);
Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6);
Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6);
Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6);
Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6);
Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6);
Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6);
Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6);
Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6);
Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6);
Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6);
Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6);
Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6);
Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6);
Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6);
Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6);
t = b1; b1 = b2; b2 = t;
Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2);
Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2);
Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2);
Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2);
Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2);
Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2);
Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2);
Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2);
Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2);
Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2);
Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2);
Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2);
Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2);
Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2);
Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2);
Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2);
Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7);
Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7);
Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7);
Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7);
Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7);
Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7);
Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7);
Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7);
Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7);
Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7);
Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7);
Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7);
Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7);
Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7);
Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7);
Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7);
t = c1; c1 = c2; c2 = t;
Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3);
Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3);
Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3);
Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3);
Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3);
Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3);
Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3);
Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3);
Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3);
Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3);
Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3);
Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3);
Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3);
Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3);
Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3);
Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3);
Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8);
Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8);
Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8);
Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8);
Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8);
Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8);
Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8);
Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8);
Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8);
Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8);
Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8);
Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8);
Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8);
Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8);
Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8);
Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8);
t = d1; d1 = d2; d2 = t;
Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4);
Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4);
Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4);
Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4);
Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4);
Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4);
Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4);
Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4);
Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4);
Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4);
Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4);
Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4);
Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4);
Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4);
Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4);
Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4);
Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9);
Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9);
Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9);
Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9);
Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9);
Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9);
Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9);
Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9);
Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9);
Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9);
Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9);
Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9);
Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9);
Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9);
Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9);
Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9);
t = e1; e1 = e2; e2 = t;
digest[0] += a1;
digest[1] += b1;
digest[2] += c1;
digest[3] += d1;
digest[4] += e1;
digest[5] += a2;
digest[6] += b2;
digest[7] += c2;
digest[8] += d2;
digest[9] += e2;
}
#undef Subround
// *************************************************************
// for 128 and 256
#define Subround(f, a, b, c, d, x, s, k) \
a += f(b, c, d) + x + k;\
a = rotlFixed((word32)a, s);
void RIPEMD128::Init()
{
m_digest[0] = 0x67452301L;
m_digest[1] = 0xefcdab89L;
m_digest[2] = 0x98badcfeL;
m_digest[3] = 0x10325476L;
}
void RIPEMD128::Transform (word32 *digest, const word32 *X)
{
unsigned long a1, b1, c1, d1, a2, b2, c2, d2;
a1 = a2 = digest[0];
b1 = b2 = digest[1];
c1 = c2 = digest[2];
d1 = d2 = digest[3];
Subround(F, a1, b1, c1, d1, X[ 0], 11, k0);
Subround(F, d1, a1, b1, c1, X[ 1], 14, k0);
Subround(F, c1, d1, a1, b1, X[ 2], 15, k0);
Subround(F, b1, c1, d1, a1, X[ 3], 12, k0);
Subround(F, a1, b1, c1, d1, X[ 4], 5, k0);
Subround(F, d1, a1, b1, c1, X[ 5], 8, k0);
Subround(F, c1, d1, a1, b1, X[ 6], 7, k0);
Subround(F, b1, c1, d1, a1, X[ 7], 9, k0);
Subround(F, a1, b1, c1, d1, X[ 8], 11, k0);
Subround(F, d1, a1, b1, c1, X[ 9], 13, k0);
Subround(F, c1, d1, a1, b1, X[10], 14, k0);
Subround(F, b1, c1, d1, a1, X[11], 15, k0);
Subround(F, a1, b1, c1, d1, X[12], 6, k0);
Subround(F, d1, a1, b1, c1, X[13], 7, k0);
Subround(F, c1, d1, a1, b1, X[14], 9, k0);
Subround(F, b1, c1, d1, a1, X[15], 8, k0);
Subround(G, a1, b1, c1, d1, X[ 7], 7, k1);
Subround(G, d1, a1, b1, c1, X[ 4], 6, k1);
Subround(G, c1, d1, a1, b1, X[13], 8, k1);
Subround(G, b1, c1, d1, a1, X[ 1], 13, k1);
Subround(G, a1, b1, c1, d1, X[10], 11, k1);
Subround(G, d1, a1, b1, c1, X[ 6], 9, k1);
Subround(G, c1, d1, a1, b1, X[15], 7, k1);
Subround(G, b1, c1, d1, a1, X[ 3], 15, k1);
Subround(G, a1, b1, c1, d1, X[12], 7, k1);
Subround(G, d1, a1, b1, c1, X[ 0], 12, k1);
Subround(G, c1, d1, a1, b1, X[ 9], 15, k1);
Subround(G, b1, c1, d1, a1, X[ 5], 9, k1);
Subround(G, a1, b1, c1, d1, X[ 2], 11, k1);
Subround(G, d1, a1, b1, c1, X[14], 7, k1);
Subround(G, c1, d1, a1, b1, X[11], 13, k1);
Subround(G, b1, c1, d1, a1, X[ 8], 12, k1);
Subround(H, a1, b1, c1, d1, X[ 3], 11, k2);
Subround(H, d1, a1, b1, c1, X[10], 13, k2);
Subround(H, c1, d1, a1, b1, X[14], 6, k2);
Subround(H, b1, c1, d1, a1, X[ 4], 7, k2);
Subround(H, a1, b1, c1, d1, X[ 9], 14, k2);
Subround(H, d1, a1, b1, c1, X[15], 9, k2);
Subround(H, c1, d1, a1, b1, X[ 8], 13, k2);
Subround(H, b1, c1, d1, a1, X[ 1], 15, k2);
Subround(H, a1, b1, c1, d1, X[ 2], 14, k2);
Subround(H, d1, a1, b1, c1, X[ 7], 8, k2);
Subround(H, c1, d1, a1, b1, X[ 0], 13, k2);
Subround(H, b1, c1, d1, a1, X[ 6], 6, k2);
Subround(H, a1, b1, c1, d1, X[13], 5, k2);
Subround(H, d1, a1, b1, c1, X[11], 12, k2);
Subround(H, c1, d1, a1, b1, X[ 5], 7, k2);
Subround(H, b1, c1, d1, a1, X[12], 5, k2);
Subround(I, a1, b1, c1, d1, X[ 1], 11, k3);
Subround(I, d1, a1, b1, c1, X[ 9], 12, k3);
Subround(I, c1, d1, a1, b1, X[11], 14, k3);
Subround(I, b1, c1, d1, a1, X[10], 15, k3);
Subround(I, a1, b1, c1, d1, X[ 0], 14, k3);
Subround(I, d1, a1, b1, c1, X[ 8], 15, k3);
Subround(I, c1, d1, a1, b1, X[12], 9, k3);
Subround(I, b1, c1, d1, a1, X[ 4], 8, k3);
Subround(I, a1, b1, c1, d1, X[13], 9, k3);
Subround(I, d1, a1, b1, c1, X[ 3], 14, k3);
Subround(I, c1, d1, a1, b1, X[ 7], 5, k3);
Subround(I, b1, c1, d1, a1, X[15], 6, k3);
Subround(I, a1, b1, c1, d1, X[14], 8, k3);
Subround(I, d1, a1, b1, c1, X[ 5], 6, k3);
Subround(I, c1, d1, a1, b1, X[ 6], 5, k3);
Subround(I, b1, c1, d1, a1, X[ 2], 12, k3);
Subround(I, a2, b2, c2, d2, X[ 5], 8, k5);
Subround(I, d2, a2, b2, c2, X[14], 9, k5);
Subround(I, c2, d2, a2, b2, X[ 7], 9, k5);
Subround(I, b2, c2, d2, a2, X[ 0], 11, k5);
Subround(I, a2, b2, c2, d2, X[ 9], 13, k5);
Subround(I, d2, a2, b2, c2, X[ 2], 15, k5);
Subround(I, c2, d2, a2, b2, X[11], 15, k5);
Subround(I, b2, c2, d2, a2, X[ 4], 5, k5);
Subround(I, a2, b2, c2, d2, X[13], 7, k5);
Subround(I, d2, a2, b2, c2, X[ 6], 7, k5);
Subround(I, c2, d2, a2, b2, X[15], 8, k5);
Subround(I, b2, c2, d2, a2, X[ 8], 11, k5);
Subround(I, a2, b2, c2, d2, X[ 1], 14, k5);
Subround(I, d2, a2, b2, c2, X[10], 14, k5);
Subround(I, c2, d2, a2, b2, X[ 3], 12, k5);
Subround(I, b2, c2, d2, a2, X[12], 6, k5);
Subround(H, a2, b2, c2, d2, X[ 6], 9, k6);
Subround(H, d2, a2, b2, c2, X[11], 13, k6);
Subround(H, c2, d2, a2, b2, X[ 3], 15, k6);
Subround(H, b2, c2, d2, a2, X[ 7], 7, k6);
Subround(H, a2, b2, c2, d2, X[ 0], 12, k6);
Subround(H, d2, a2, b2, c2, X[13], 8, k6);
Subround(H, c2, d2, a2, b2, X[ 5], 9, k6);
Subround(H, b2, c2, d2, a2, X[10], 11, k6);
Subround(H, a2, b2, c2, d2, X[14], 7, k6);
Subround(H, d2, a2, b2, c2, X[15], 7, k6);
Subround(H, c2, d2, a2, b2, X[ 8], 12, k6);
Subround(H, b2, c2, d2, a2, X[12], 7, k6);
Subround(H, a2, b2, c2, d2, X[ 4], 6, k6);
Subround(H, d2, a2, b2, c2, X[ 9], 15, k6);
Subround(H, c2, d2, a2, b2, X[ 1], 13, k6);
Subround(H, b2, c2, d2, a2, X[ 2], 11, k6);
Subround(G, a2, b2, c2, d2, X[15], 9, k7);
Subround(G, d2, a2, b2, c2, X[ 5], 7, k7);
Subround(G, c2, d2, a2, b2, X[ 1], 15, k7);
Subround(G, b2, c2, d2, a2, X[ 3], 11, k7);
Subround(G, a2, b2, c2, d2, X[ 7], 8, k7);
Subround(G, d2, a2, b2, c2, X[14], 6, k7);
Subround(G, c2, d2, a2, b2, X[ 6], 6, k7);
Subround(G, b2, c2, d2, a2, X[ 9], 14, k7);
Subround(G, a2, b2, c2, d2, X[11], 12, k7);
Subround(G, d2, a2, b2, c2, X[ 8], 13, k7);
Subround(G, c2, d2, a2, b2, X[12], 5, k7);
Subround(G, b2, c2, d2, a2, X[ 2], 14, k7);
Subround(G, a2, b2, c2, d2, X[10], 13, k7);
Subround(G, d2, a2, b2, c2, X[ 0], 13, k7);
Subround(G, c2, d2, a2, b2, X[ 4], 7, k7);
Subround(G, b2, c2, d2, a2, X[13], 5, k7);
Subround(F, a2, b2, c2, d2, X[ 8], 15, k9);
Subround(F, d2, a2, b2, c2, X[ 6], 5, k9);
Subround(F, c2, d2, a2, b2, X[ 4], 8, k9);
Subround(F, b2, c2, d2, a2, X[ 1], 11, k9);
Subround(F, a2, b2, c2, d2, X[ 3], 14, k9);
Subround(F, d2, a2, b2, c2, X[11], 14, k9);
Subround(F, c2, d2, a2, b2, X[15], 6, k9);
Subround(F, b2, c2, d2, a2, X[ 0], 14, k9);
Subround(F, a2, b2, c2, d2, X[ 5], 6, k9);
Subround(F, d2, a2, b2, c2, X[12], 9, k9);
Subround(F, c2, d2, a2, b2, X[ 2], 12, k9);
Subround(F, b2, c2, d2, a2, X[13], 9, k9);
Subround(F, a2, b2, c2, d2, X[ 9], 12, k9);
Subround(F, d2, a2, b2, c2, X[ 7], 5, k9);
Subround(F, c2, d2, a2, b2, X[10], 15, k9);
Subround(F, b2, c2, d2, a2, X[14], 8, k9);
c1 = digest[1] + c1 + d2;
digest[1] = digest[2] + d1 + a2;
digest[2] = digest[3] + a1 + b2;
digest[3] = digest[0] + b1 + c2;
digest[0] = c1;
}
// *************************************************************
void RIPEMD256::Init()
{
m_digest[0] = 0x67452301L;
m_digest[1] = 0xefcdab89L;
m_digest[2] = 0x98badcfeL;
m_digest[3] = 0x10325476L;
m_digest[4] = 0x76543210L;
m_digest[5] = 0xfedcba98L;
m_digest[6] = 0x89abcdefL;
m_digest[7] = 0x01234567L;
}
void RIPEMD256::Transform (word32 *digest, const word32 *X)
{
unsigned long a1, b1, c1, d1, a2, b2, c2, d2, t;
a1 = digest[0];
b1 = digest[1];
c1 = digest[2];
d1 = digest[3];
a2 = digest[4];
b2 = digest[5];
c2 = digest[6];
d2 = digest[7];
Subround(F, a1, b1, c1, d1, X[ 0], 11, k0);
Subround(F, d1, a1, b1, c1, X[ 1], 14, k0);
Subround(F, c1, d1, a1, b1, X[ 2], 15, k0);
Subround(F, b1, c1, d1, a1, X[ 3], 12, k0);
Subround(F, a1, b1, c1, d1, X[ 4], 5, k0);
Subround(F, d1, a1, b1, c1, X[ 5], 8, k0);
Subround(F, c1, d1, a1, b1, X[ 6], 7, k0);
Subround(F, b1, c1, d1, a1, X[ 7], 9, k0);
Subround(F, a1, b1, c1, d1, X[ 8], 11, k0);
Subround(F, d1, a1, b1, c1, X[ 9], 13, k0);
Subround(F, c1, d1, a1, b1, X[10], 14, k0);
Subround(F, b1, c1, d1, a1, X[11], 15, k0);
Subround(F, a1, b1, c1, d1, X[12], 6, k0);
Subround(F, d1, a1, b1, c1, X[13], 7, k0);
Subround(F, c1, d1, a1, b1, X[14], 9, k0);
Subround(F, b1, c1, d1, a1, X[15], 8, k0);
Subround(I, a2, b2, c2, d2, X[ 5], 8, k5);
Subround(I, d2, a2, b2, c2, X[14], 9, k5);
Subround(I, c2, d2, a2, b2, X[ 7], 9, k5);
Subround(I, b2, c2, d2, a2, X[ 0], 11, k5);
Subround(I, a2, b2, c2, d2, X[ 9], 13, k5);
Subround(I, d2, a2, b2, c2, X[ 2], 15, k5);
Subround(I, c2, d2, a2, b2, X[11], 15, k5);
Subround(I, b2, c2, d2, a2, X[ 4], 5, k5);
Subround(I, a2, b2, c2, d2, X[13], 7, k5);
Subround(I, d2, a2, b2, c2, X[ 6], 7, k5);
Subround(I, c2, d2, a2, b2, X[15], 8, k5);
Subround(I, b2, c2, d2, a2, X[ 8], 11, k5);
Subround(I, a2, b2, c2, d2, X[ 1], 14, k5);
Subround(I, d2, a2, b2, c2, X[10], 14, k5);
Subround(I, c2, d2, a2, b2, X[ 3], 12, k5);
Subround(I, b2, c2, d2, a2, X[12], 6, k5);
t = a1; a1 = a2; a2 = t;
Subround(G, a1, b1, c1, d1, X[ 7], 7, k1);
Subround(G, d1, a1, b1, c1, X[ 4], 6, k1);
Subround(G, c1, d1, a1, b1, X[13], 8, k1);
Subround(G, b1, c1, d1, a1, X[ 1], 13, k1);
Subround(G, a1, b1, c1, d1, X[10], 11, k1);
Subround(G, d1, a1, b1, c1, X[ 6], 9, k1);
Subround(G, c1, d1, a1, b1, X[15], 7, k1);
Subround(G, b1, c1, d1, a1, X[ 3], 15, k1);
Subround(G, a1, b1, c1, d1, X[12], 7, k1);
Subround(G, d1, a1, b1, c1, X[ 0], 12, k1);
Subround(G, c1, d1, a1, b1, X[ 9], 15, k1);
Subround(G, b1, c1, d1, a1, X[ 5], 9, k1);
Subround(G, a1, b1, c1, d1, X[ 2], 11, k1);
Subround(G, d1, a1, b1, c1, X[14], 7, k1);
Subround(G, c1, d1, a1, b1, X[11], 13, k1);
Subround(G, b1, c1, d1, a1, X[ 8], 12, k1);
Subround(H, a2, b2, c2, d2, X[ 6], 9, k6);
Subround(H, d2, a2, b2, c2, X[11], 13, k6);
Subround(H, c2, d2, a2, b2, X[ 3], 15, k6);
Subround(H, b2, c2, d2, a2, X[ 7], 7, k6);
Subround(H, a2, b2, c2, d2, X[ 0], 12, k6);
Subround(H, d2, a2, b2, c2, X[13], 8, k6);
Subround(H, c2, d2, a2, b2, X[ 5], 9, k6);
Subround(H, b2, c2, d2, a2, X[10], 11, k6);
Subround(H, a2, b2, c2, d2, X[14], 7, k6);
Subround(H, d2, a2, b2, c2, X[15], 7, k6);
Subround(H, c2, d2, a2, b2, X[ 8], 12, k6);
Subround(H, b2, c2, d2, a2, X[12], 7, k6);
Subround(H, a2, b2, c2, d2, X[ 4], 6, k6);
Subround(H, d2, a2, b2, c2, X[ 9], 15, k6);
Subround(H, c2, d2, a2, b2, X[ 1], 13, k6);
Subround(H, b2, c2, d2, a2, X[ 2], 11, k6);
t = b1; b1 = b2; b2 = t;
Subround(H, a1, b1, c1, d1, X[ 3], 11, k2);
Subround(H, d1, a1, b1, c1, X[10], 13, k2);
Subround(H, c1, d1, a1, b1, X[14], 6, k2);
Subround(H, b1, c1, d1, a1, X[ 4], 7, k2);
Subround(H, a1, b1, c1, d1, X[ 9], 14, k2);
Subround(H, d1, a1, b1, c1, X[15], 9, k2);
Subround(H, c1, d1, a1, b1, X[ 8], 13, k2);
Subround(H, b1, c1, d1, a1, X[ 1], 15, k2);
Subround(H, a1, b1, c1, d1, X[ 2], 14, k2);
Subround(H, d1, a1, b1, c1, X[ 7], 8, k2);
Subround(H, c1, d1, a1, b1, X[ 0], 13, k2);
Subround(H, b1, c1, d1, a1, X[ 6], 6, k2);
Subround(H, a1, b1, c1, d1, X[13], 5, k2);
Subround(H, d1, a1, b1, c1, X[11], 12, k2);
Subround(H, c1, d1, a1, b1, X[ 5], 7, k2);
Subround(H, b1, c1, d1, a1, X[12], 5, k2);
Subround(G, a2, b2, c2, d2, X[15], 9, k7);
Subround(G, d2, a2, b2, c2, X[ 5], 7, k7);
Subround(G, c2, d2, a2, b2, X[ 1], 15, k7);
Subround(G, b2, c2, d2, a2, X[ 3], 11, k7);
Subround(G, a2, b2, c2, d2, X[ 7], 8, k7);
Subround(G, d2, a2, b2, c2, X[14], 6, k7);
Subround(G, c2, d2, a2, b2, X[ 6], 6, k7);
Subround(G, b2, c2, d2, a2, X[ 9], 14, k7);
Subround(G, a2, b2, c2, d2, X[11], 12, k7);
Subround(G, d2, a2, b2, c2, X[ 8], 13, k7);
Subround(G, c2, d2, a2, b2, X[12], 5, k7);
Subround(G, b2, c2, d2, a2, X[ 2], 14, k7);
Subround(G, a2, b2, c2, d2, X[10], 13, k7);
Subround(G, d2, a2, b2, c2, X[ 0], 13, k7);
Subround(G, c2, d2, a2, b2, X[ 4], 7, k7);
Subround(G, b2, c2, d2, a2, X[13], 5, k7);
t = c1; c1 = c2; c2 = t;
Subround(I, a1, b1, c1, d1, X[ 1], 11, k3);
Subround(I, d1, a1, b1, c1, X[ 9], 12, k3);
Subround(I, c1, d1, a1, b1, X[11], 14, k3);
Subround(I, b1, c1, d1, a1, X[10], 15, k3);
Subround(I, a1, b1, c1, d1, X[ 0], 14, k3);
Subround(I, d1, a1, b1, c1, X[ 8], 15, k3);
Subround(I, c1, d1, a1, b1, X[12], 9, k3);
Subround(I, b1, c1, d1, a1, X[ 4], 8, k3);
Subround(I, a1, b1, c1, d1, X[13], 9, k3);
Subround(I, d1, a1, b1, c1, X[ 3], 14, k3);
Subround(I, c1, d1, a1, b1, X[ 7], 5, k3);
Subround(I, b1, c1, d1, a1, X[15], 6, k3);
Subround(I, a1, b1, c1, d1, X[14], 8, k3);
Subround(I, d1, a1, b1, c1, X[ 5], 6, k3);
Subround(I, c1, d1, a1, b1, X[ 6], 5, k3);
Subround(I, b1, c1, d1, a1, X[ 2], 12, k3);
Subround(F, a2, b2, c2, d2, X[ 8], 15, k9);
Subround(F, d2, a2, b2, c2, X[ 6], 5, k9);
Subround(F, c2, d2, a2, b2, X[ 4], 8, k9);
Subround(F, b2, c2, d2, a2, X[ 1], 11, k9);
Subround(F, a2, b2, c2, d2, X[ 3], 14, k9);
Subround(F, d2, a2, b2, c2, X[11], 14, k9);
Subround(F, c2, d2, a2, b2, X[15], 6, k9);
Subround(F, b2, c2, d2, a2, X[ 0], 14, k9);
Subround(F, a2, b2, c2, d2, X[ 5], 6, k9);
Subround(F, d2, a2, b2, c2, X[12], 9, k9);
Subround(F, c2, d2, a2, b2, X[ 2], 12, k9);
Subround(F, b2, c2, d2, a2, X[13], 9, k9);
Subround(F, a2, b2, c2, d2, X[ 9], 12, k9);
Subround(F, d2, a2, b2, c2, X[ 7], 5, k9);
Subround(F, c2, d2, a2, b2, X[10], 15, k9);
Subround(F, b2, c2, d2, a2, X[14], 8, k9);
t = d1; d1 = d2; d2 = t;
digest[0] += a1;
digest[1] += b1;
digest[2] += c1;
digest[3] += d1;
digest[4] += a2;
digest[5] += b2;
digest[6] += c2;
digest[7] += d2;
}
NAMESPACE_END NAMESPACE_END

View File

@ -19,6 +19,45 @@ protected:
void Init(); void Init();
}; };
/*! Digest Length = 320 bits, Security = 160 bits */
class RIPEMD320 : public IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD320>
{
public:
enum {DIGESTSIZE = 40};
RIPEMD320() : IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD320>(DIGESTSIZE) {Init();}
static void Transform(word32 *digest, const word32 *data);
static const char * StaticAlgorithmName() {return "RIPEMD-320";}
protected:
void Init();
};
/*! Digest Length = 128 bits */
class RIPEMD128 : public IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD128>
{
public:
enum {DIGESTSIZE = 16};
RIPEMD128() : IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD128>(DIGESTSIZE) {Init();}
static void Transform(word32 *digest, const word32 *data);
static const char * StaticAlgorithmName() {return "RIPEMD-128";}
protected:
void Init();
};
/*! Digest Length = 256 bits, Security = 128 bits */
class RIPEMD256 : public IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD256>
{
public:
enum {DIGESTSIZE = 32};
RIPEMD256() : IteratedHashWithStaticTransform<word32, LittleEndian, 64, RIPEMD256>(DIGESTSIZE) {Init();}
static void Transform(word32 *digest, const word32 *data);
static const char * StaticAlgorithmName() {return "RIPEMD-256";}
protected:
void Init();
};
NAMESPACE_END NAMESPACE_END
#endif #endif

16
rng.cpp
View File

@ -116,22 +116,24 @@ MaurerRandomnessTest::MaurerRandomnessTest()
tab[i] = 0; tab[i] = 0;
} }
inline void MaurerRandomnessTest::Put(byte inByte) unsigned int MaurerRandomnessTest::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{ {
while (length--)
{
byte inByte = *inString++;
if (n >= Q) if (n >= Q)
sum += log(double(n - tab[inByte])); sum += log(double(n - tab[inByte]));
tab[inByte] = n; tab[inByte] = n;
n++; n++;
} }
return 0;
void MaurerRandomnessTest::Put(const byte *inString, unsigned int length)
{
while (length--)
Put(*inString++);
} }
double MaurerRandomnessTest::GetTestValue() const double MaurerRandomnessTest::GetTestValue() const
{ {
if (BytesNeeded() > 0)
throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed");
double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer
double value = fTu * 0.1392; // arbitrarily normalize it to double value = fTu * 0.1392; // arbitrarily normalize it to

5
rng.h
View File

@ -50,13 +50,12 @@ private:
it is intended for measuring the randomness of *PHYSICAL* RNGs. it is intended for measuring the randomness of *PHYSICAL* RNGs.
For more details see his paper in Journal of Cryptology, 1992. */ For more details see his paper in Journal of Cryptology, 1992. */
class MaurerRandomnessTest : public Sink class MaurerRandomnessTest : public Bufferless<Sink>
{ {
public: public:
MaurerRandomnessTest(); MaurerRandomnessTest();
void Put(byte inByte); unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
void Put(const byte *inString, unsigned int length);
// BytesNeeded() returns how many more bytes of input is needed by the test // BytesNeeded() returns how many more bytes of input is needed by the test
// GetTestValue() should not be called before BytesNeeded()==0 // GetTestValue() should not be called before BytesNeeded()==0

View File

@ -201,6 +201,13 @@ int main(int argc, char *argv[])
} }
} }
case 'm': case 'm':
if (command == "mt")
{
MaurerRandomnessTest mt;
FileStore(argv[2]).TransferAllTo(mt);
cout << "Maurer Test Value: " << mt.GetTestValue() << endl;
}
else
DigestFile(argv[2]); DigestFile(argv[2]);
return 0; return 0;
case 't': case 't':
@ -547,7 +554,7 @@ void RSASignFile(const char *privFilename, const char *messageFilename, const ch
FileSource privFile(privFilename, true, new HexDecoder); FileSource privFile(privFilename, true, new HexDecoder);
RSASSA_PKCS1v15_SHA_Signer priv(privFile); RSASSA_PKCS1v15_SHA_Signer priv(privFile);
// RSASSA_PKCS1v15_SHA_Signer ignores the rng. Use a real RNG for other signature schemes! // RSASSA_PKCS1v15_SHA_Signer ignores the rng. Use a real RNG for other signature schemes!
FileSource f(messageFilename, true, new SignerFilter(NullRNG(), priv, new HexEncoder(new FileSink(signatureFilename)))); FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename))));
} }
bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename) bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename)
@ -922,6 +929,10 @@ bool Validate(int alg, bool thorough, const char *seed)
case 57: result = ValidateESIGN(); break; case 57: result = ValidateESIGN(); break;
case 58: result = ValidateDLIES(); break; case 58: result = ValidateDLIES(); break;
case 59: result = ValidateBaseCode(); break; case 59: result = ValidateBaseCode(); break;
case 60: result = ValidateSHACAL2(); break;
case 61: result = ValidateCamellia(); break;
case 62: result = ValidateWhirlpool(); break;
case 63: result = ValidateTTMAC(); break;
default: result = ValidateAll(thorough); break; default: result = ValidateAll(thorough); break;
} }

View File

@ -59,6 +59,12 @@ Test Driver for Crypto++(TM) Library, a C++ Class Library of Cryptographic Schem
- To run the FIPS 140-2 sample application - To run the FIPS 140-2 sample application
cryptest fips cryptest fips
- To generate 100000 random files using FIPS Approved X.917 RNG
cryptest fips-rand
- To run Maurer's randomness test on a file
cryptest mt input
- To run validation tests - To run validation tests
cryptest v cryptest v

View File

@ -29,6 +29,8 @@
#include "twofish.h" #include "twofish.h"
#include "serpent.h" #include "serpent.h"
#include "skipjack.h" #include "skipjack.h"
#include "shacal2.h"
#include "camellia.h"
#include "osrng.h" #include "osrng.h"
#include "zdeflate.h" #include "zdeflate.h"
@ -58,10 +60,12 @@ bool ValidateAll(bool thorough)
pass=ValidateTiger() && pass; pass=ValidateTiger() && pass;
pass=ValidateRIPEMD() && pass; pass=ValidateRIPEMD() && pass;
pass=ValidatePanama() && pass; pass=ValidatePanama() && pass;
pass=ValidateWhirlpool() && pass;
pass=ValidateMD5MAC() && pass; pass=ValidateMD5MAC() && pass;
pass=ValidateHMAC() && pass; pass=ValidateHMAC() && pass;
pass=ValidateXMACC() && pass; pass=ValidateXMACC() && pass;
pass=ValidateTTMAC() && pass;
pass=ValidatePBKDF() && pass; pass=ValidatePBKDF() && pass;
@ -86,6 +90,8 @@ bool ValidateAll(bool thorough)
pass=ValidateRijndael() && pass; pass=ValidateRijndael() && pass;
pass=ValidateTwofish() && pass; pass=ValidateTwofish() && pass;
pass=ValidateSerpent() && pass; pass=ValidateSerpent() && pass;
pass=ValidateSHACAL2() && pass;
pass=ValidateCamellia() && pass;
pass=ValidateBBS() && pass; pass=ValidateBBS() && pass;
pass=ValidateDH() && pass; pass=ValidateDH() && pass;
@ -1308,3 +1314,31 @@ bool ValidateBaseCode()
return pass; return pass;
} }
bool ValidateSHACAL2()
{
cout << "\nSHACAL-2 validation suite running...\n\n";
bool pass = true;
FileSource valdata("shacal2v.dat", true, new HexDecoder);
pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(16), valdata, 4) && pass;
pass = BlockTransformationTest(FixedRoundsCipherFactory<SHACAL2Encryption, SHACAL2Decryption>(64), valdata, 10) && pass;
return pass;
}
bool ValidateCamellia()
{
cout << "\nCamellia validation suite running...\n\n";
#ifdef WORD64_AVAILABLE
bool pass = true;
FileSource valdata("camellia.dat", true, new HexDecoder);
pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(16), valdata, 15) && pass;
pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(24), valdata, 15) && pass;
pass = BlockTransformationTest(FixedRoundsCipherFactory<CamelliaEncryption, CamelliaDecryption>(32), valdata, 15) && pass;
return pass;
#else
cout << "word64 not available, skipping Camellia validation." << endl;
return true;
#endif
}

View File

@ -14,10 +14,12 @@
#include "ripemd.h" #include "ripemd.h"
#include "haval.h" #include "haval.h"
#include "panama.h" #include "panama.h"
#include "whrlpool.h"
#include "md5mac.h" #include "md5mac.h"
#include "hmac.h" #include "hmac.h"
#include "xormac.h" #include "xormac.h"
#include "ttmac.h"
#include "integer.h" #include "integer.h"
#include "pwdbased.h" #include "pwdbased.h"
@ -189,18 +191,6 @@ bool ValidateSHA2()
HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"), HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1"),
}; };
HashTestTuple testSet384[] =
{
HashTestTuple("abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7"),
HashTestTuple("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39"),
};
HashTestTuple testSet512[] =
{
HashTestTuple("abc", "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"),
HashTestTuple("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"),
};
bool pass = true; bool pass = true;
cout << "\nSHA-256 validation suite running...\n\n"; cout << "\nSHA-256 validation suite running...\n\n";
@ -208,12 +198,34 @@ bool ValidateSHA2()
pass = HashModuleTest(sha256, testSet256, sizeof(testSet256)/sizeof(testSet256[0])) && pass; pass = HashModuleTest(sha256, testSet256, sizeof(testSet256)/sizeof(testSet256[0])) && pass;
cout << "\nSHA-384 validation suite running...\n\n"; cout << "\nSHA-384 validation suite running...\n\n";
#ifdef WORD64_AVAILABLE
HashTestTuple testSet384[] =
{
HashTestTuple("abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7"),
HashTestTuple("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91\x74\x60\x39"),
};
SHA384 sha384; SHA384 sha384;
pass = HashModuleTest(sha384, testSet384, sizeof(testSet384)/sizeof(testSet384[0])) && pass; pass = HashModuleTest(sha384, testSet384, sizeof(testSet384)/sizeof(testSet384[0])) && pass;
#else
cout << "word64 not available, skipping SHA-384 validation." << endl;
#endif
cout << "\nSHA-512 validation suite running...\n\n"; cout << "\nSHA-512 validation suite running...\n\n";
#ifdef WORD64_AVAILABLE
HashTestTuple testSet512[] =
{
HashTestTuple("abc", "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f"),
HashTestTuple("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09"),
};
SHA512 sha512; SHA512 sha512;
pass = HashModuleTest(sha512, testSet512, sizeof(testSet512)/sizeof(testSet512[0])) && pass; pass = HashModuleTest(sha512, testSet512, sizeof(testSet512)/sizeof(testSet512[0])) && pass;
#else
cout << "word64 not available, skipping SHA-512 validation." << endl;
#endif
return pass; return pass;
} }
@ -247,7 +259,20 @@ bool ValidateTiger()
bool ValidateRIPEMD() bool ValidateRIPEMD()
{ {
HashTestTuple testSet[] = HashTestTuple testSet128[] =
{
HashTestTuple("", "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e\xcb\x61\x0f\x18\xf6\xb3\x8b\x46"),
HashTestTuple("a", "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7\xcf\xc7\x85\xe7\x2f\x57\x8d\x33"),
HashTestTuple("abc", "\xc1\x4a\x12\x19\x9c\x66\xe4\xba\x84\x63\x6b\x0f\x69\x14\x4c\x77"),
HashTestTuple("message digest", "\x9e\x32\x7b\x3d\x6e\x52\x30\x62\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8"),
HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5\x10\x71\x49\x22\xb3\x71\x83\x4e"),
HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d\xdc\x22\xe8\x8b\x49\x13\x3a\x06"),
HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f\xae\xa4\x62\x4c\x60\xc5\xc7\x02"),
HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x3f\x45\xef\x19\x47\x32\xc2\xdb\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3"),
HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x4a\x7f\x57\x23\xf9\x54\xeb\xa1\x21\x6c\x9d\x8f\x63\x20\x43\x1f", 15625)
};
HashTestTuple testSet160[] =
{ {
HashTestTuple("", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31"), HashTestTuple("", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31"),
HashTestTuple("a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe"), HashTestTuple("a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe"),
@ -260,10 +285,51 @@ bool ValidateRIPEMD()
HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83\x25\xdc\x15\x28", 15625) HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\x52\x78\x32\x43\xc1\x69\x7b\xdb\xe1\x6d\x37\xf9\x7f\x68\xf0\x83\x25\xdc\x15\x28", 15625)
}; };
RIPEMD160 md; HashTestTuple testSet256[] =
{
HashTestTuple("", "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18\x77\xfc\x52\xd6\x4d\x30\xe3\x7a\x2d\x97\x74\xfb\x1e\x5d\x02\x63\x80\xae\x01\x68\xe3\xc5\x52\x2d"),
HashTestTuple("a", "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9\x0a\x91\xba\xb7\x0a\x1e\xba\x0c\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf\xcd\x88\x3a\x91\x34\x69\x29\x25"),
HashTestTuple("abc", "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb\xce\xf5\xca\x2d\x03\xe6\xdb\xa1\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e\x1e\x42\xd2\xe9\x75\x45\x9b\x65"),
HashTestTuple("message digest", "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a\x51\x4d\x5c\x91\x4c\x39\x2c\x90\x18\xc7\xc4\x6b\xc1\x44\x65\x55\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e"),
HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\x64\x9d\x30\x34\x75\x1e\xa2\x16\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc\x78\x96\x11\x8a\x51\x97\x96\x87\x82\xdd\x1f\xd9\x7d\x8d\x51\x33"),
HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x38\x43\x04\x55\x83\xaa\xc6\xc8\xc8\xd9\x12\x85\x73\xe7\xa9\x80\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f"),
HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x57\x40\xa4\x08\xac\x16\xb7\x20\xb8\x44\x24\xae\x93\x1c\xbb\x1f\xe3\x63\xd1\xd0\xbf\x40\x17\xf1\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8"),
HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x06\xfd\xcc\x7a\x40\x95\x48\xaa\xf9\x13\x68\xc0\x6a\x62\x75\xb5\x53\xe3\xf0\x99\xbf\x0e\xa4\xed\xfd\x67\x78\xdf\x89\xa8\x90\xdd"),
HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xac\x95\x37\x44\xe1\x0e\x31\x51\x4c\x15\x0d\x4d\x8d\x7b\x67\x73\x42\xe3\x33\x99\x78\x82\x96\xe4\x3a\xe4\x85\x0c\xe4\xf9\x79\x78", 15625)
};
HashTestTuple testSet320[] =
{
HashTestTuple("", "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8"),
HashTestTuple("a", "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d"),
HashTestTuple("abc", "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d"),
HashTestTuple("message digest", "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97"),
HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09"),
HashTestTuple("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac"),
HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4"),
HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42"),
HashTestTuple("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "\xbd\xee\x37\xf4\x37\x1e\x20\x64\x6b\x8b\x0d\x86\x2d\xda\x16\x29\x2a\xe3\x6f\x40\x96\x5e\x8c\x85\x09\xe6\x3d\x1d\xbd\xde\xcc\x50\x3e\x2b\x63\xeb\x92\x45\xbb\x66", 15625)
};
bool pass = true;
cout << "\nRIPEMD-128 validation suite running...\n\n";
RIPEMD128 md128;
pass = HashModuleTest(md128, testSet128, sizeof(testSet128)/sizeof(testSet128[0])) && pass;
cout << "\nRIPEMD-160 validation suite running...\n\n"; cout << "\nRIPEMD-160 validation suite running...\n\n";
return HashModuleTest(md, testSet, sizeof(testSet)/sizeof(testSet[0])); RIPEMD160 md160;
pass = HashModuleTest(md160, testSet160, sizeof(testSet160)/sizeof(testSet160[0])) && pass;
cout << "\nRIPEMD-256 validation suite running...\n\n";
RIPEMD256 md256;
pass = HashModuleTest(md256, testSet256, sizeof(testSet256)/sizeof(testSet256[0])) && pass;
cout << "\nRIPEMD-320 validation suite running...\n\n";
RIPEMD320 md320;
pass = HashModuleTest(md320, testSet320, sizeof(testSet320)/sizeof(testSet320[0])) && pass;
return pass;
} }
bool ValidateHAVAL() bool ValidateHAVAL()
@ -390,6 +456,62 @@ bool ValidatePanama()
return pass; return pass;
} }
bool ValidateWhirlpool()
{
cout << "\nWhirlpool Hash Function validation suite running...\n\n";
#ifdef WORD64_AVAILABLE
// Selected test vectors from the Whirlpool NESSIE submission.
const char Output0[] =
"\x47\x0F\x04\x09\xAB\xAA\x44\x6E\x49\x66\x7D\x4E\xBE\x12\xA1\x43"
"\x87\xCE\xDB\xD1\x0D\xD1\x7B\x82\x43\xCA\xD5\x50\xA0\x89\xDC\x0F"
"\xEE\xA7\xAA\x40\xF6\xC2\xAA\xAB\x71\xC6\xEB\xD0\x76\xE4\x3C\x7C"
"\xFC\xA0\xAD\x32\x56\x78\x97\xDC\xB5\x96\x98\x61\x04\x9A\x0F\x5A";
const char Output1[] =
"\xEB\xAA\x1D\xF2\xE9\x71\x13\xBE\x18\x7E\xB0\x30\x3C\x66\x0F\x6E"
"\x64\x3E\x2C\x09\x0E\xF2\xCD\xA9\xA2\xEA\x6D\xCF\x50\x02\x14\x7D"
"\x1D\x0E\x1E\x9D\x99\x6E\x87\x9C\xEF\x9D\x26\x89\x66\x30\xA5\xDB"
"\x33\x08\xD5\xA0\xDC\x23\x5B\x19\x9C\x38\x92\x3B\xE2\x25\x9E\x03";
const char Output16[] =
"\x40\x23\x8F\x57\xB2\x7D\x07\x4F\x9C\x8D\x04\x3D\xBD\x27\x07\xC7"
"\x18\xFC\x34\x49\xCC\x1F\x49\x0C\xA2\xF3\x24\xDF\xEC\x48\xB0\x5A"
"\xE7\x2D\x02\x6D\x89\x1C\xC0\x80\xE6\x31\x1F\xC3\x2E\xCF\xFC\x30"
"\xF4\x23\xDA\x7E\x63\xE3\x98\x7C\xA0\xCD\x37\xBF\xFD\x97\xCA\x56";
const char Output32[] =
"\x48\xCC\xE9\x1F\x62\xB6\xD9\x35\x13\x38\x30\x1D\xF1\x82\xF4\x6A"
"\xD0\x7B\xB7\xB2\x33\xC1\x19\xCA\x2C\x1F\xC2\x19\xFF\xF9\x49\x85"
"\x8D\x47\xE5\x0D\x69\x18\xEB\xDC\xDF\x5F\x82\x98\x05\xFB\x86\x07"
"\x22\x76\x35\x69\xE6\xAB\x73\x41\x05\x4C\x38\x9C\xE9\xD6\xEB\xAC";
const char Output33[] =
"\x60\x4B\x8B\x59\x15\xA7\xD6\x21\x42\x78\xDF\x08\x13\x53\x1F\xF2"
"\x60\xE1\x46\x51\xEC\xAC\xEC\x57\x6F\x01\xC4\x05\x42\x8F\x8D\x55"
"\x45\xB7\xEA\x6E\x65\x75\x8E\x5E\x83\xA4\x29\xD8\x52\xF4\x8C\x16"
"\x50\x6B\xBF\x00\xB5\x28\x51\x9B\x14\x2A\x77\x45\xF8\x31\x84\xD4";
const char Output64[] =
"\xA0\x72\x51\x3B\x2A\xA9\xE0\x72\x26\xBA\x01\xE7\xD5\xB2\xB6\x26"
"\xE3\x62\xB1\x40\x1E\x1A\xEC\xF1\x68\xB9\x53\x32\x42\xC0\x18\xFF"
"\xEA\x81\x83\x7F\x7B\xD1\x60\xD1\xD0\xA9\x64\x4C\x8E\xD6\x41\x50"
"\xE6\x40\x6D\x2C\x1B\x74\x56\x02\x4F\x10\x98\x53\x90\x81\xFC\x77";
HashTestTuple testSet[] =
{
HashTestTuple("", 0, Output0, 1),
HashTestTuple("\0", 1, Output1, 1),
HashTestTuple("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, Output16, 1),
HashTestTuple("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, Output32, 2),
HashTestTuple("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 33, Output33, 1),
HashTestTuple("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, Output64, 4),
};
Whirlpool whirlpool;
return HashModuleTest(whirlpool, testSet, sizeof(testSet)/sizeof(testSet[0]));
#else
cout << "word64 not available, skipping Whirlpool validation." << endl;
return true;
#endif
}
bool ValidateMD5MAC() bool ValidateMD5MAC()
{ {
const byte keys[2][MD5MAC::KEYLENGTH]={ const byte keys[2][MD5MAC::KEYLENGTH]={
@ -557,6 +679,54 @@ bool ValidateXMACC()
return pass; return pass;
} }
bool ValidateTTMAC()
{
const byte key[TTMAC::KEYLENGTH]={
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,
0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x01,0x23,0x45,0x67};
const char *TestVals[8]={
"",
"a",
"abc",
"message digest",
"abcdefghijklmnopqrstuvwxyz",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"};
const byte output[8][TTMAC::DIGESTSIZE]={
{0x2d,0xec,0x8e,0xd4,0xa0,0xfd,0x71,0x2e,0xd9,0xfb,0xf2,0xab,0x46,0x6e,0xc2,0xdf,0x21,0x21,0x5e,0x4a},
{0x58,0x93,0xe3,0xe6,0xe3,0x06,0x70,0x4d,0xd7,0x7a,0xd6,0xe6,0xed,0x43,0x2c,0xde,0x32,0x1a,0x77,0x56},
{0x70,0xbf,0xd1,0x02,0x97,0x97,0xa5,0xc1,0x6d,0xa5,0xb5,0x57,0xa1,0xf0,0xb2,0x77,0x9b,0x78,0x49,0x7e},
{0x82,0x89,0xf4,0xf1,0x9f,0xfe,0x4f,0x2a,0xf7,0x37,0xde,0x4b,0xd7,0x1c,0x82,0x9d,0x93,0xa9,0x72,0xfa},
{0x21,0x86,0xca,0x09,0xc5,0x53,0x31,0x98,0xb7,0x37,0x1f,0x24,0x52,0x73,0x50,0x4c,0xa9,0x2b,0xae,0x60},
{0x8a,0x7b,0xf7,0x7a,0xef,0x62,0xa2,0x57,0x84,0x97,0xa2,0x7c,0x0d,0x65,0x18,0xa4,0x29,0xe7,0xc1,0x4d},
{0x54,0xba,0xc3,0x92,0xa8,0x86,0x80,0x6d,0x16,0x95,0x56,0xfc,0xbb,0x67,0x89,0xb5,0x4f,0xb3,0x64,0xfb},
{0x0c,0xed,0x2c,0x9f,0x8f,0x0d,0x9d,0x03,0x98,0x1a,0xb5,0xc8,0x18,0x4b,0xac,0x43,0xdd,0x54,0xc4,0x84}};
byte digest[TTMAC::DIGESTSIZE];
bool pass=true, fail;
cout << "\nTwo-Track-MAC validation suite running...\n";
TTMAC mac(key, sizeof(key));
for (int k=0; k<sizeof(TestVals)/sizeof(TestVals[0]); k++)
{
mac.Update((byte *)TestVals[k], strlen(TestVals[k]));
mac.Final(digest);
fail = memcmp(digest, output[k], TTMAC::DIGESTSIZE)
|| !mac.VerifyDigest(output[k], (byte *)TestVals[k], strlen(TestVals[k]));
pass = pass && !fail;
cout << (fail ? "FAILED " : "passed ");
for (int j=0;j<TTMAC::DIGESTSIZE;j++)
cout << setw(2) << setfill('0') << hex << (int)digest[j];
cout << " \"" << TestVals[k] << '\"' << endl;
}
return true;
}
struct PBKDF_TestTuple struct PBKDF_TestTuple
{ {
byte purpose; byte purpose;

View File

@ -20,10 +20,12 @@ bool ValidateHAVAL();
bool ValidateTiger(); bool ValidateTiger();
bool ValidateRIPEMD(); bool ValidateRIPEMD();
bool ValidatePanama(); bool ValidatePanama();
bool ValidateWhirlpool();
bool ValidateMD5MAC(); bool ValidateMD5MAC();
bool ValidateHMAC(); bool ValidateHMAC();
bool ValidateXMACC(); bool ValidateXMACC();
bool ValidateTTMAC();
bool ValidateCipherModes(); bool ValidateCipherModes();
bool ValidatePBKDF(); bool ValidatePBKDF();
@ -49,6 +51,8 @@ bool ValidateMARS();
bool ValidateRijndael(); bool ValidateRijndael();
bool ValidateTwofish(); bool ValidateTwofish();
bool ValidateSerpent(); bool ValidateSerpent();
bool ValidateSHACAL2();
bool ValidateCamellia();
bool ValidateBBS(); bool ValidateBBS();
bool ValidateDH(); bool ValidateDH();