summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--License.txt1
-rw-r--r--TestVectors/all.txt4
-rw-r--r--argnames.h6
-rw-r--r--basecode.cpp3
-rw-r--r--bench.cpp17
-rw-r--r--channels.cpp189
-rw-r--r--channels.h48
-rw-r--r--cryptest.cpp5
-rw-r--r--cryptest.dsp26
-rw-r--r--cryptlib.dsp34
-rw-r--r--files.cpp21
-rw-r--r--files.h14
-rw-r--r--filters.cpp4
-rw-r--r--filters.h43
-rw-r--r--fipsalgt.cpp877
-rw-r--r--fipstest.cpp42
-rw-r--r--md2.cpp13
-rw-r--r--misc.h65
-rw-r--r--regtest.cpp9
-rw-r--r--ripemd.cpp610
-rw-r--r--ripemd.h39
-rw-r--r--rng.cpp22
-rw-r--r--rng.h5
-rw-r--r--test.cpp15
-rw-r--r--usage.dat6
-rw-r--r--validat1.cpp34
-rw-r--r--validat3.cpp198
-rw-r--r--validate.h4
29 files changed, 2185 insertions, 171 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 942f7bd..39f841f 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -44,7 +44,7 @@ endif
OBJS = $(SRCS:.cpp=.o)
# 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))
all: cryptest.exe
diff --git a/License.txt b/License.txt
index 2a8ec4e..fb48551 100644
--- a/License.txt
+++ b/License.txt
@@ -26,6 +26,7 @@ Chris Morgan - rijndael.cpp
Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp
Richard De Moliner - safer.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
any purpose, including commercial applications, is hereby granted
diff --git a/TestVectors/all.txt b/TestVectors/all.txt
index 62d4479..64bd7f3 100644
--- a/TestVectors/all.txt
+++ b/TestVectors/all.txt
@@ -1,5 +1,9 @@
AlgorithmType: FileList
Name: all.txt collection
+Test: camelia.txt
+Test: shacal2.txt
+Test: ttmac.txt
+Test: whrlpool.txt
Test: dlies.txt
Test: dsa.txt
Test: dsa_1363.txt
diff --git a/argnames.h b/argnames.h
index ed227ee..ebeda1b 100644
--- a/argnames.h
+++ b/argnames.h
@@ -46,6 +46,12 @@ CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32
CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter
CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter
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
diff --git a/basecode.cpp b/basecode.cpp
index 1e81ece..8fe41be 100644
--- a/basecode.cpp
+++ b/basecode.cpp
@@ -221,7 +221,10 @@ unsigned int Grouper::Put2(const byte *begin, unsigned int length, int messageEn
FILTER_OUTPUT(3, begin, length, 0);
if (messageEnd)
+ {
FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
+ m_counter = 0;
+ }
FILTER_END_NO_MESSAGE_END
}
diff --git a/bench.cpp b/bench.cpp
index 44c0c96..8670d37 100644
--- a/bench.cpp
+++ b/bench.cpp
@@ -12,6 +12,7 @@
#include "tiger.h"
#include "ripemd.h"
#include "panama.h"
+#include "whrlpool.h"
#include "idea.h"
#include "des.h"
#include "rc2.h"
@@ -33,10 +34,13 @@
#include "rijndael.h"
#include "twofish.h"
#include "serpent.h"
+#include "shacal2.h"
+#include "camellia.h"
#include "hmac.h"
#include "xormac.h"
#include "cbcmac.h"
#include "dmac.h"
+#include "ttmac.h"
#include "blumshub.h"
#include "rsa.h"
#include "nr.h"
@@ -438,7 +442,9 @@ void BenchMarkAll(double t)
BenchMarkKeyless<MD5>("MD5", t);
BenchMarkKeyless<SHA>("SHA-1", t);
BenchMarkKeyless<SHA256>("SHA-256", t);
+#ifdef WORD64_AVAILABLE
BenchMarkKeyless<SHA512>("SHA-512", t);
+#endif
BenchMarkKeyless<HAVAL3>("HAVAL (pass=3)", t);
BenchMarkKeyless<HAVAL4>("HAVAL (pass=4)", t);
BenchMarkKeyless<HAVAL5>("HAVAL (pass=5)", t);
@@ -448,6 +454,9 @@ void BenchMarkAll(double t)
BenchMarkKeyless<RIPEMD160>("RIPE-MD160", t);
BenchMarkKeyless<PanamaHash<LittleEndian> >("Panama Hash (little 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<LR<MD5>::Encryption>("Luby-Rackoff/MD5", t);
BenchMarkKeyed<DES::Encryption>("DES", t);
@@ -490,9 +499,17 @@ void BenchMarkAll(double t)
BenchMarkKeyed<WAKE_OFB<LittleEndian>::Encryption>("WAKE-OFB-LE", t);
BenchMarkKeyed<PanamaCipher<LittleEndian>::Encryption>("Panama Cipher (little 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<XMACC<MD5> >("XMACC/MD5", t);
BenchMarkKeyed<HMAC<MD5> >("HMAC/MD5", t);
+ BenchMarkKeyed<TTMAC>("Two-Track-MAC", t);
BenchMarkKeyed<CBC_MAC<Rijndael> >("CBC-MAC/Rijndael", t);
BenchMarkKeyed<DMAC<Rijndael> >("DMAC/Rijndael", t);
diff --git a/channels.cpp b/channels.cpp
index d13bcf4..7bb31dd 100644
--- a/channels.cpp
+++ b/channels.cpp
@@ -85,73 +85,82 @@ void MessageSwitch::MessageSeriesEnd(int propagation=-1);
*/
#endif
-class ChannelRouteIterator
-{
-public:
- typedef ChannelSwitch::RouteMap::const_iterator MapIterator;
- 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
+//////////////////////////
- ChannelRouteIterator(ChannelSwitch &cs, const std::string &channel)
- : m_channel(channel)
+void ChannelRouteIterator::Reset(const std::string &channel)
+{
+ m_channel = channel;
+ pair<MapIterator, MapIterator> range = m_cs.m_routeMap.equal_range(channel);
+ if (range.first == range.second)
{
- pair<MapIterator, MapIterator> range = cs.m_routeMap.equal_range(channel);
- if (range.first == range.second)
- {
- m_useDefault = true;
- m_itListCurrent = cs.m_defaultRoutes.begin();
- m_itListEnd = cs.m_defaultRoutes.end();
- }
- else
- {
- m_useDefault = false;
- m_itMapCurrent = range.first;
- m_itMapEnd = range.second;
- }
+ m_useDefault = true;
+ m_itListCurrent = m_cs.m_defaultRoutes.begin();
+ m_itListEnd = m_cs.m_defaultRoutes.end();
}
-
- bool End() const
+ else
{
- return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
+ m_useDefault = false;
+ m_itMapCurrent = range.first;
+ m_itMapEnd = range.second;
}
+}
- void Next()
- {
- if (m_useDefault)
- ++m_itListCurrent;
- else
- ++m_itMapCurrent;
- }
+bool ChannelRouteIterator::End() const
+{
+ return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd;
+}
- BufferedTransformation & Destination()
- {
- return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
- }
+void ChannelRouteIterator::Next()
+{
+ if (m_useDefault)
+ ++m_itListCurrent;
+ else
+ ++m_itMapCurrent;
+}
- const std::string & Channel()
- {
- if (m_useDefault)
- return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
- else
- return m_itMapCurrent->second.second;
- }
-};
+BufferedTransformation & ChannelRouteIterator::Destination()
+{
+ return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first;
+}
+
+const std::string & ChannelRouteIterator::Channel()
+{
+ if (m_useDefault)
+ return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel;
+ else
+ return m_itMapCurrent->second.second;
+}
+
+
+//
+// ChannelSwitch
+///////////////////
unsigned int ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking)
{
- if (!blocking)
- throw BlockingInputOnly("ChannelSwitch");
+ if (m_blocked)
+ {
+ m_blocked = false;
+ goto WasBlocked;
+ }
- ChannelRouteIterator it(*this, channel);
- while (!it.End())
+ m_it.Reset(channel);
+
+ while (!m_it.End())
{
- it.Destination().ChannelPut2(it.Channel(), begin, length, messageEnd, blocking);
- it.Next();
+ WasBlocked:
+ if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking))
+ {
+ m_blocked = true;
+ return 1;
+ }
+
+ m_it.Next();
}
+
return 0;
}
@@ -163,51 +172,74 @@ void ChannelSwitch::ChannelInitialize(const std::string &channel, const NameValu
m_defaultRoutes.clear();
}
- ChannelRouteIterator it(*this, channel);
- while (!it.End())
+ m_it.Reset(channel);
+
+ while (!m_it.End())
{
- it.Destination().ChannelInitialize(it.Channel(), parameters, propagation);
- it.Next();
+ m_it.Destination().ChannelInitialize(m_it.Channel(), parameters, propagation);
+ m_it.Next();
}
}
bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
{
- if (!blocking)
- throw BlockingInputOnly("ChannelSwitch");
+ if (m_blocked)
+ {
+ m_blocked = false;
+ goto WasBlocked;
+ }
- ChannelRouteIterator it(*this, channel);
- while (!it.End())
+ m_it.Reset(channel);
+
+ while (!m_it.End())
{
- it.Destination().ChannelFlush(it.Channel(), completeFlush, propagation, blocking);
- it.Next();
+ WasBlocked:
+ if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking))
+ {
+ m_blocked = true;
+ return true;
+ }
+
+ m_it.Next();
}
+
return false;
}
bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
{
- if (!blocking)
- throw BlockingInputOnly("ChannelSwitch");
+ if (m_blocked)
+ {
+ m_blocked = false;
+ goto WasBlocked;
+ }
- ChannelRouteIterator it(*this, channel);
- while (!it.End())
+ m_it.Reset(channel);
+
+ while (!m_it.End())
{
- it.Destination().ChannelMessageSeriesEnd(it.Channel(), propagation);
- it.Next();
+ WasBlocked:
+ if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation))
+ {
+ m_blocked = true;
+ return true;
+ }
+
+ m_it.Next();
}
+
return false;
}
byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, unsigned int &size)
{
- ChannelRouteIterator it(*this, channel);
- if (!it.End())
+ m_it.Reset(channel);
+ if (!m_it.End())
{
- BufferedTransformation &target = it.Destination();
- it.Next();
- if (it.End()) // there is only one target channel
- return target.ChannelCreatePutSpace(it.Channel(), size);
+ BufferedTransformation &target = m_it.Destination();
+ m_it.Next();
+ if (m_it.End()) // there is only one target channel
+ return target.ChannelCreatePutSpace(m_it.Channel(), size);
}
size = 0;
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)
{
- if (!blocking)
- throw BlockingInputOnly("ChannelSwitch");
+ ChannelRouteIterator it(*this);
+ it.Reset(channel);
- ChannelRouteIterator it(*this, channel);
if (!it.End())
{
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
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)
diff --git a/channels.h b/channels.h
index 4b12ce6..cc9aa66 100644
--- a/channels.h
+++ b/channels.h
@@ -44,16 +44,48 @@ private:
};
#endif
+class ChannelSwitchTypedefs
+{
+public:
+ typedef std::pair<BufferedTransformation *, std::string> Route;
+ 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>
+class ChannelSwitch : public Multichannel<Sink>, public ChannelSwitchTypedefs
{
public:
- ChannelSwitch() {}
- ChannelSwitch(BufferedTransformation &destination)
+ ChannelSwitch() : m_it(*this), m_blocked(false) {}
+ ChannelSwitch(BufferedTransformation &destination) : m_it(*this), m_blocked(false)
{
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);
}
@@ -75,14 +107,12 @@ public:
void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel);
private:
- typedef std::pair<BufferedTransformation *, std::string> Route;
- typedef std::multimap<std::string, Route> RouteMap;
RouteMap m_routeMap;
-
- typedef std::pair<BufferedTransformation *, value_ptr<std::string> > DefaultRoute;
- typedef std::list<DefaultRoute> DefaultRouteList;
DefaultRouteList m_defaultRoutes;
+ ChannelRouteIterator m_it;
+ bool m_blocked;
+
friend class ChannelRouteIterator;
};
diff --git a/cryptest.cpp b/cryptest.cpp
index 5302331..9aea0ba 100644
--- a/cryptest.cpp
+++ b/cryptest.cpp
@@ -14,6 +14,7 @@ USEUNIT("bfinit.cpp");
USEUNIT("blowfish.cpp");
USEUNIT("blumgold.cpp");
USEUNIT("blumshub.cpp");
+USEUNIT("camellia.cpp");
USEUNIT("cast.cpp");
USEUNIT("cast128s.cpp");
USEUNIT("crc.cpp");
@@ -62,11 +63,11 @@ USEUNIT("ripemd.cpp");
USEUNIT("rng.cpp");
USEUNIT("rsa.cpp");
USEUNIT("safer.cpp");
-USEUNIT("sapphire.cpp");
USEUNIT("seal.cpp");
USEUNIT("secshare.cpp");
USEUNIT("secsplit.cpp");
USEUNIT("sha.cpp");
+USEUNIT("shacal2.cpp");
USEUNIT("shark.cpp");
USEUNIT("sharkbox.cpp");
USEUNIT("square.cpp");
@@ -75,10 +76,12 @@ USEUNIT("tea.cpp");
USEUNIT("test.cpp");
USEUNIT("tiger.cpp");
USEUNIT("tigertab.cpp");
+USEUNIT("ttmac.cpp");
USEUNIT("validat1.cpp");
USEUNIT("validat2.cpp");
USEUNIT("validat3.cpp");
USEUNIT("wake.cpp");
+USEUNIT("whrlpool.cpp");
USEUNIT("zbits.cpp");
USEUNIT("zdeflate.cpp");
USEUNIT("zinflate.cpp");
diff --git a/cryptest.dsp b/cryptest.dsp
index 74e0dc1..f7fb19e 100644
--- a/cryptest.dsp
+++ b/cryptest.dsp
@@ -1,5 +1,5 @@
# 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 **
# 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 Target_Dir ""
# 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 RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -126,7 +126,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# 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 RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -157,6 +157,14 @@ SOURCE=.\3wayval.dat
# End 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
# End Source File
# Begin Source File
@@ -225,6 +233,10 @@ SOURCE=.\ideaval.dat
# End Source File
# Begin Source File
+SOURCE=.\khazadv.dat
+# End Source File
+# Begin Source File
+
SOURCE=.\luc1024.dat
# End Source File
# Begin Source File
@@ -337,6 +349,14 @@ SOURCE=.\serpentv.dat
# End 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
# End Source File
# Begin Source File
diff --git a/cryptlib.dsp b/cryptlib.dsp
index bbf78d3..1c32dd0 100644
--- a/cryptlib.dsp
+++ b/cryptlib.dsp
@@ -1,5 +1,5 @@
# 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 **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
@@ -230,6 +230,10 @@ SOURCE=.\blumshub.cpp
# End Source File
# Begin Source File
+SOURCE=.\camellia.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\cast.cpp
# End Source File
# Begin Source File
@@ -527,6 +531,10 @@ SOURCE=.\sha.cpp
# End Source File
# Begin Source File
+SOURCE=.\shacal2.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\shark.cpp
# End Source File
# Begin Source File
@@ -579,6 +587,10 @@ SOURCE=.\trdlocal.cpp
# End Source File
# Begin Source File
+SOURCE=.\ttmac.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\twofish.cpp
# End Source File
# Begin Source File
@@ -591,6 +603,10 @@ SOURCE=.\wake.cpp
# End Source File
# Begin Source File
+SOURCE=.\whrlpool.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\winpipes.cpp
# End Source File
# Begin Source File
@@ -667,6 +683,10 @@ SOURCE=.\blumshub.h
# End Source File
# Begin Source File
+SOURCE=.\camellia.h
+# End Source File
+# Begin Source File
+
SOURCE=.\cast.h
# End Source File
# Begin Source File
@@ -991,6 +1011,10 @@ SOURCE=.\sha.h
# End Source File
# Begin Source File
+SOURCE=.\shacal2.h
+# End Source File
+# Begin Source File
+
SOURCE=.\shark.h
# End Source File
# Begin Source File
@@ -1035,6 +1059,10 @@ SOURCE=.\trunhash.h
# End Source File
# Begin Source File
+SOURCE=.\ttmac.h
+# End Source File
+# Begin Source File
+
SOURCE=.\twofish.h
# End Source File
# Begin Source File
@@ -1047,6 +1075,10 @@ SOURCE=.\wake.h
# End Source File
# Begin Source File
+SOURCE=.\whrlpool.h
+# End Source File
+# Begin Source File
+
SOURCE=.\winpipes.h
# End Source File
# Begin Source File
diff --git a/files.cpp b/files.cpp
index 2b42010..fc32b4b 100644
--- a/files.cpp
+++ b/files.cpp
@@ -16,10 +16,12 @@ void Files_TestInstantiations()
void FileStore::StoreInitialize(const NameValuePairs &parameters)
{
+ m_file.close();
+ m_file.clear();
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);
if (!m_file)
throw OpenErr(fileName);
@@ -28,7 +30,7 @@ void FileStore::StoreInitialize(const NameValuePairs &parameters)
else
{
m_stream = NULL;
- parameters.GetValue("InputStreamPointer", m_stream);
+ parameters.GetValue(Name::InputStreamPointer(), m_stream);
}
m_waiting = false;
}
@@ -137,12 +139,19 @@ unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned lo
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)
{
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);
if (!m_file)
throw OpenErr(fileName);
@@ -151,7 +160,7 @@ void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
else
{
m_stream = NULL;
- parameters.GetValue("OutputStreamPointer", m_stream);
+ parameters.GetValue(Name::OutputStreamPointer(), m_stream);
}
}
diff --git a/files.h b/files.h
index 2c0c52d..fc3d650 100644
--- a/files.h
+++ b/files.h
@@ -3,6 +3,7 @@
#include "cryptlib.h"
#include "filters.h"
+#include "argnames.h"
#include <iostream>
#include <fstream>
@@ -23,15 +24,16 @@ public:
FileStore() : m_stream(NULL) {}
FileStore(std::istream &in)
- {StoreInitialize(MakeParameters("InputStreamPointer", &in));}
+ {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));}
FileStore(const char *filename)
- {StoreInitialize(MakeParameters("InputFileName", filename));}
+ {StoreInitialize(MakeParameters(Name::InputFileName(), filename));}
std::istream* GetStream() {return m_stream;}
unsigned long MaxRetrievable() const;
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 long Skip(unsigned long skipMax=ULONG_MAX);
private:
void StoreInitialize(const NameValuePairs &parameters);
@@ -54,9 +56,9 @@ public:
FileSource(BufferedTransformation *attachment = NULL)
: SourceTemplate<FileStore>(attachment) {}
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)
- : 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();}
};
@@ -75,9 +77,9 @@ public:
FileSink() : m_stream(NULL) {}
FileSink(std::ostream &out)
- {IsolatedInitialize(MakeParameters("OutputStreamPointer", &out));}
+ {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));}
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;}
diff --git a/filters.cpp b/filters.cpp
index 64c2a37..4c4d660 100644
--- a/filters.cpp
+++ b/filters.cpp
@@ -381,10 +381,10 @@ void Redirector::ChannelInitialize(const std::string &channel, const NameValuePa
if (channel.empty())
{
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);
}
diff --git a/filters.h b/filters.h
index b2ddec2..c5d8641 100644
--- a/filters.h
+++ b/filters.h
@@ -366,36 +366,55 @@ typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibili
class Redirector : public CustomSignalPropagation<Sink>
{
public:
- Redirector() : m_target(NULL), m_passSignal(true) {}
- Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
+ enum Behavior
+ {
+ 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 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)
- {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)
{ChannelInitialize(NULL_CHANNEL, parameters, propagation);}
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)
- {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);
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)
- {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)
- {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)
- {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:
BufferedTransformation *m_target;
- bool m_passSignal;
+ word32 m_behavior;
};
// Used By ProxyFilter
diff --git a/fipsalgt.cpp b/fipsalgt.cpp
new file mode 100644
index 0000000..4537ee4
--- /dev/null
+++ b/fipsalgt.cpp
@@ -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);
+}
+*/
diff --git a/fipstest.cpp b/fipstest.cpp
index 10368ae..9f740f0 100644
--- a/fipstest.cpp
+++ b/fipstest.cpp
@@ -42,6 +42,7 @@ void X917RNG_KnownAnswerTest(
unsigned int deterministicTimeVector,
CIPHER *dummy = NULL)
{
+#ifdef OS_RNG_AVAILABLE
std::string decodedKey, decodedSeed;
StringSource(key, true, new HexDecoder(new StringSink(decodedKey)));
StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed)));
@@ -49,6 +50,9 @@ void X917RNG_KnownAnswerTest(
AutoSeededX917RNG<CIPHER> rng;
rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), deterministicTimeVector);
KnownAnswerTest(rng, output);
+#else
+ throw 0;
+#endif
}
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>
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::Verifier verifier(signer);
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")));
comparison.ChannelMessageSeriesEnd("0");
comparison.ChannelMessageSeriesEnd("1");
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));
}
@@ -222,7 +232,33 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha
SHA1 sha;
HashVerifier verifier(sha);
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())
{
#ifdef CRYPTOPP_WIN32_AVAILABLE
diff --git a/md2.cpp b/md2.cpp
index aa1a28c..a010dc0 100644
--- a/md2.cpp
+++ b/md2.cpp
@@ -80,8 +80,17 @@ void MD2::Update(const byte *buf, unsigned int len)
t=0;
for(i=0; i<18; i++)
{
- for(j=0; j<48; j++)
- t=m_X[j]^=S[t];
+ for(j=0; j<48; j+=8)
+ {
+ 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;
}
}
diff --git a/misc.h b/misc.h
index 1e341e2..527a058 100644
--- a/misc.h
+++ b/misc.h
@@ -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);
}
+#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>
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>
inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
{
diff --git a/regtest.cpp b/regtest.cpp
index d691d46..60e59f7 100644
--- a/regtest.cpp
+++ b/regtest.cpp
@@ -1,5 +1,6 @@
#include "factory.h"
+#include "modes.h"
#include "dh.h"
#include "esign.h"
#include "md2.h"
@@ -10,6 +11,10 @@
#include "ripemd.h"
#include "dsa.h"
#include "seal.h"
+#include "whrlpool.h"
+#include "ttmac.h"
+#include "camellia.h"
+#include "shacal2.h"
USING_NAMESPACE(CryptoPP)
@@ -20,9 +25,11 @@ void RegisterFactories()
RegisterDefaultFactoryFor<HashTransformation, SHA256>("SHA-256");
RegisterDefaultFactoryFor<HashTransformation, SHA384>("SHA-384");
RegisterDefaultFactoryFor<HashTransformation, SHA512>("SHA-512");
+ RegisterDefaultFactoryFor<HashTransformation, Whirlpool>("Whirlpool");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<MD5> >("HMAC(MD5)");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >("HMAC(SHA-1)");
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >("HMAC(RIPEMD-160)");
+ RegisterDefaultFactoryFor<MessageAuthenticationCode, TTMAC >("Two-Track-MAC");
RegisterAsymmetricCipherDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)");
RegisterAsymmetricCipherDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)");
RegisterSignatureSchemeDefaultFactories<DSA>("DSA(1363)");
@@ -34,4 +41,6 @@ void RegisterFactories()
RegisterSignatureSchemeDefaultFactories<RWSS<P1363_EMSA2, SHA1> >("RW/EMSA2(SHA-1)");
RegisterSignatureSchemeDefaultFactories<RSASS<PSS, SHA1> >("RSA/PSS-MGF1(SHA-1)");
RegisterSymmetricCipherDefaultFactories<SEAL<> >("SEAL-3.0-BE");
+ RegisterSymmetricCipherDefaultFactories<ECB_Mode<Camellia> >("Camellia(ECB)");
+ RegisterSymmetricCipherDefaultFactories<ECB_Mode<SHACAL2> >("SHACAL-2(ECB)");
}
diff --git a/ripemd.cpp b/ripemd.cpp
index ac0a840..4bdcfc5 100644
--- a/ripemd.cpp
+++ b/ripemd.cpp
@@ -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 "ripemd.h"
@@ -6,22 +9,6 @@
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 G(x, y, z) (z ^ (x & (y^z)))
#define H(x, y, z) (z ^ (x | ~y))
@@ -39,6 +26,25 @@ void RIPEMD160::Transform (word32 *digest, const word32 *X)
#define k8 0x7a6d76e9UL
#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;
a1 = a2 = digest[0];
b1 = b2 = digest[1];
@@ -224,4 +230,574 @@ void RIPEMD160::Transform (word32 *digest, const word32 *X)
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
diff --git a/ripemd.h b/ripemd.h
index 6ac8e71..f128158 100644
--- a/ripemd.h
+++ b/ripemd.h
@@ -19,6 +19,45 @@ protected:
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
#endif
diff --git a/rng.cpp b/rng.cpp
index 0119d30..dfcd262 100644
--- a/rng.cpp
+++ b/rng.cpp
@@ -116,22 +116,24 @@ MaurerRandomnessTest::MaurerRandomnessTest()
tab[i] = 0;
}
-inline void MaurerRandomnessTest::Put(byte inByte)
-{
- if (n >= Q)
- sum += log(double(n - tab[inByte]));
- tab[inByte] = n;
- n++;
-}
-
-void MaurerRandomnessTest::Put(const byte *inString, unsigned int length)
+unsigned int MaurerRandomnessTest::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
{
while (length--)
- Put(*inString++);
+ {
+ byte inByte = *inString++;
+ if (n >= Q)
+ sum += log(double(n - tab[inByte]));
+ tab[inByte] = n;
+ n++;
+ }
+ return 0;
}
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 value = fTu * 0.1392; // arbitrarily normalize it to
diff --git a/rng.h b/rng.h
index 5b0998d..1ca082e 100644
--- a/rng.h
+++ b/rng.h
@@ -50,13 +50,12 @@ private:
it is intended for measuring the randomness of *PHYSICAL* RNGs.
For more details see his paper in Journal of Cryptology, 1992. */
-class MaurerRandomnessTest : public Sink
+class MaurerRandomnessTest : public Bufferless<Sink>
{
public:
MaurerRandomnessTest();
- void Put(byte inByte);
- void Put(const byte *inString, unsigned int length);
+ unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking);
// BytesNeeded() returns how many more bytes of input is needed by the test
// GetTestValue() should not be called before BytesNeeded()==0
diff --git a/test.cpp b/test.cpp
index 21eb4f3..964eabb 100644
--- a/test.cpp
+++ b/test.cpp
@@ -201,7 +201,14 @@ int main(int argc, char *argv[])
}
}
case 'm':
- DigestFile(argv[2]);
+ if (command == "mt")
+ {
+ MaurerRandomnessTest mt;
+ FileStore(argv[2]).TransferAllTo(mt);
+ cout << "Maurer Test Value: " << mt.GetTestValue() << endl;
+ }
+ else
+ DigestFile(argv[2]);
return 0;
case 't':
{
@@ -547,7 +554,7 @@ void RSASignFile(const char *privFilename, const char *messageFilename, const ch
FileSource privFile(privFilename, true, new HexDecoder);
RSASSA_PKCS1v15_SHA_Signer priv(privFile);
// 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)
@@ -922,6 +929,10 @@ bool Validate(int alg, bool thorough, const char *seed)
case 57: result = ValidateESIGN(); break;
case 58: result = ValidateDLIES(); 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;
}
diff --git a/usage.dat b/usage.dat
index d885914..eb92a43 100644
--- a/usage.dat
+++ b/usage.dat
@@ -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
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
cryptest v
diff --git a/validat1.cpp b/validat1.cpp
index c71a0f4..ed3f26a 100644
--- a/validat1.cpp
+++ b/validat1.cpp
@@ -29,6 +29,8 @@
#include "twofish.h"
#include "serpent.h"
#include "skipjack.h"
+#include "shacal2.h"
+#include "camellia.h"
#include "osrng.h"
#include "zdeflate.h"
@@ -58,10 +60,12 @@ bool ValidateAll(bool thorough)
pass=ValidateTiger() && pass;
pass=ValidateRIPEMD() && pass;
pass=ValidatePanama() && pass;
+ pass=ValidateWhirlpool() && pass;
pass=ValidateMD5MAC() && pass;
pass=ValidateHMAC() && pass;
pass=ValidateXMACC() && pass;
+ pass=ValidateTTMAC() && pass;
pass=ValidatePBKDF() && pass;
@@ -86,6 +90,8 @@ bool ValidateAll(bool thorough)
pass=ValidateRijndael() && pass;
pass=ValidateTwofish() && pass;
pass=ValidateSerpent() && pass;
+ pass=ValidateSHACAL2() && pass;
+ pass=ValidateCamellia() && pass;
pass=ValidateBBS() && pass;
pass=ValidateDH() && pass;
@@ -1308,3 +1314,31 @@ bool ValidateBaseCode()
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
+}
diff --git a/validat3.cpp b/validat3.cpp
index aa7aae1..e5ea465 100644
--- a/validat3.cpp
+++ b/validat3.cpp
@@ -14,10 +14,12 @@
#include "ripemd.h"
#include "haval.h"
#include "panama.h"
+#include "whrlpool.h"
#include "md5mac.h"
#include "hmac.h"
#include "xormac.h"
+#include "ttmac.h"
#include "integer.h"
#include "pwdbased.h"
@@ -189,31 +191,41 @@ 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"),
};
+ bool pass = true;
+
+ cout << "\nSHA-256 validation suite running...\n\n";
+ SHA256 sha256;
+ pass = HashModuleTest(sha256, testSet256, sizeof(testSet256)/sizeof(testSet256[0])) && pass;
+
+ 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;
+ 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";
+
+#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"),
};
- bool pass = true;
-
- cout << "\nSHA-256 validation suite running...\n\n";
- SHA256 sha256;
- pass = HashModuleTest(sha256, testSet256, sizeof(testSet256)/sizeof(testSet256[0])) && pass;
-
- cout << "\nSHA-384 validation suite running...\n\n";
- SHA384 sha384;
- pass = HashModuleTest(sha384, testSet384, sizeof(testSet384)/sizeof(testSet384[0])) && pass;
-
- cout << "\nSHA-512 validation suite running...\n\n";
SHA512 sha512;
pass = HashModuleTest(sha512, testSet512, sizeof(testSet512)/sizeof(testSet512[0])) && pass;
+#else
+ cout << "word64 not available, skipping SHA-512 validation." << endl;
+#endif
return pass;
}
@@ -247,7 +259,20 @@ bool ValidateTiger()
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("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)
};
- 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";
- 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()
@@ -390,6 +456,62 @@ bool ValidatePanama()
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()
{
const byte keys[2][MD5MAC::KEYLENGTH]={
@@ -557,6 +679,54 @@ bool ValidateXMACC()
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
{
byte purpose;
diff --git a/validate.h b/validate.h
index 486cf48..4bf69b8 100644
--- a/validate.h
+++ b/validate.h
@@ -20,10 +20,12 @@ bool ValidateHAVAL();
bool ValidateTiger();
bool ValidateRIPEMD();
bool ValidatePanama();
+bool ValidateWhirlpool();
bool ValidateMD5MAC();
bool ValidateHMAC();
bool ValidateXMACC();
+bool ValidateTTMAC();
bool ValidateCipherModes();
bool ValidatePBKDF();
@@ -49,6 +51,8 @@ bool ValidateMARS();
bool ValidateRijndael();
bool ValidateTwofish();
bool ValidateSerpent();
+bool ValidateSHACAL2();
+bool ValidateCamellia();
bool ValidateBBS();
bool ValidateDH();