OSDN Git Service

Simplified QKeccakHash and added self-test function.
authorLoRd_MuldeR <mulder2@gmx.de>
Tue, 27 Nov 2012 00:02:55 +0000 (01:02 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Tue, 27 Nov 2012 00:02:55 +0000 (01:02 +0100)
etc/Prerequisites/keccak/lib/Debug/QKeccakHash_VS2010.lib
etc/Prerequisites/keccak/lib/Release/QKeccakHash_VS2010.lib
etc/Prerequisites/keccak/lib/Release_Static/QKeccakHash_VS2010.lib
etc/Prerequisites/keccak/src/qkeccakhash.cpp
etc/Prerequisites/keccak/src/qkeccakhash.h
src/Config.h
src/LockedFile.cpp
src/LockedFile.h
src/Thread_Initialization.cpp

index ca9dc38..1ef9925 100644 (file)
Binary files a/etc/Prerequisites/keccak/lib/Debug/QKeccakHash_VS2010.lib and b/etc/Prerequisites/keccak/lib/Debug/QKeccakHash_VS2010.lib differ
index 6a43c43..f18b04f 100644 (file)
Binary files a/etc/Prerequisites/keccak/lib/Release/QKeccakHash_VS2010.lib and b/etc/Prerequisites/keccak/lib/Release/QKeccakHash_VS2010.lib differ
index 28cc17a..6954da8 100644 (file)
Binary files a/etc/Prerequisites/keccak/lib/Release_Static/QKeccakHash_VS2010.lib and b/etc/Prerequisites/keccak/lib/Release_Static/QKeccakHash_VS2010.lib differ
index 9a03c5b..0d680ad 100644 (file)
 
 #include "keccakimpl.cpp"
 
-QKeccakHash::QKeccakHash() :
-  mState(0),
-  mHashBitLength(0)
+QKeccakHash::QKeccakHash()
 {
-}
-
-QKeccakHash::QKeccakHash(const QString &asciiMessage, HashBits hashBits) :
-  mState(0),
-  mHashBitLength(0)
-{
-  if (!setHashBitLength(hashBits))
-    return;
-  
-  bool success = false;
-  QByteArray msg = asciiMessage.toAscii();
-  
-  mState = new KeccakImpl::hashState;
-  if (KeccakImpl::Init(mState, mHashBitLength) == KeccakImpl::SUCCESS)
-  {
-    if (KeccakImpl::Update(mState, (KeccakImpl::BitSequence*)msg.constData(), msg.size()*8) == KeccakImpl::SUCCESS)
-    {
-      if (KeccakImpl::Final(mState, (KeccakImpl::BitSequence*)mHashResult.data()) == KeccakImpl::SUCCESS)
-        success = true;
-    }
-  }
-  delete mState;
-  mState = 0;
-  
-  if (!success)
-  {
-    mHashResult.clear();
-    qDebug() << "QKeccakHash::QKeccakHash(): hash construction failed";
-  }
+       m_initialized = false;
+       m_state = new KeccakImpl::hashState;
+       memset(m_state, 0, sizeof(KeccakImpl::hashState));
+       m_hashResult.clear();
 }
 
 QKeccakHash::~QKeccakHash()
 {
-  if (mState)
-    delete mState;
-}
-
-QByteArray QKeccakHash::toRaw() const
-{
-  return mHashResult;
-}
-
-QByteArray QKeccakHash::toHex() const
-{
-  return mHashResult.toHex();
-}
+       m_hashResult.clear();
 
-QString QKeccakHash::toHexString() const
-{
-  return QString(mHashResult.toHex());
-}
-
-bool QKeccakHash::file(const QString &fileName, HashBits hashBits, int blockSize)
-{
-  if (isBatchRunning() || blockSize < 1)
-    return false;
-  if (!setHashBitLength(hashBits))
-    return false;
-  QFile file(fileName);
-  if (file.open(QFile::ReadOnly))
-  {
-    qint64 fileSize = file.size();
-    qint64 readBytes = 0;
-    if (!startBatch())
-      return false;
-    bool success = true;
-    char *buffer = new char[blockSize];
-    // repeatedly read blockSize bytes of the file to buffer and pass it to putBatch:
-    while (file.error() == QFile::NoError)
-    {
-      readBytes = file.read(buffer, qMin(fileSize-file.pos(), (qint64)blockSize)); // read till end of file to buffer, but not more than blockSize bytes
-      if (readBytes > 0)
-      {
-        if (!putBatch(buffer, readBytes))
-        {
-          success = false;
-          break;
-        }
-        if (readBytes < blockSize) // that was the last block
-          break;
-      } else // error occured
-      {
-        success = false;
-        break;
-      }
-    }
-    delete buffer;
-    if (!stopBatch())
-      success = false;
-    return success;
-  } else
-    return false;
+       if(m_state)
+       {
+               delete m_state;
+               m_state = NULL;
+       }
 }
 
-bool QKeccakHash::startBatch(HashBits hashBits)
+bool QKeccakHash::init(HashBits hashBits)
 {
-  if (isBatchRunning())
-    return false;
-  if (!setHashBitLength(hashBits))
-    return false;
-  mState = new KeccakImpl::hashState;
-  bool success = KeccakImpl::Init(mState, mHashBitLength) == KeccakImpl::SUCCESS;
-  if (!success)
-  {
-    delete mState;
-    mState = 0;
-    mHashResult.clear();
-  }
-  return success;
+       if(m_initialized)
+       {
+               qWarning("QKeccakHash has already been initialized!");
+               return false;
+       }
+
+       m_hashResult.clear();
+       memset(m_state, 0, sizeof(KeccakImpl::hashState));
+       int hashBitLength = 0;
+
+       switch (hashBits)
+       {
+               case hb224: hashBitLength = 224; break;
+               case hb256: hashBitLength = 256; break;
+               case hb384: hashBitLength = 384; break;
+               case hb512: hashBitLength = 512; break;
+               default: throw "Invalid hash length!!";
+       }
+
+       if(KeccakImpl::Init(m_state, hashBitLength) != KeccakImpl::SUCCESS)
+       {
+               qWarning("KeccakImpl::Init() has failed unexpectedly!");
+               return false;
+       }
+       
+       m_hashResult.fill(char(0), hashBitLength/8);
+       m_initialized = true;
+
+       return true;
 }
 
-bool QKeccakHash::putBatch(const QByteArray &ba)
+bool QKeccakHash::addData(const QByteArray &data)
 {
-  return putBatch(ba.constData(), ba.size());
+       return addData(data.constData(), data.size());
 }
 
-bool QKeccakHash::putBatch(const char *data, int size)
+bool QKeccakHash::addData(const char *data, int size)
 {
-  if (!isBatchRunning() || mHashBitLength == 0)
-    return false;
-  bool success = KeccakImpl::Update(mState, (KeccakImpl::BitSequence*)data, size*8) == KeccakImpl::SUCCESS;
-  if (!success)
-  {
-    delete mState;
-    mState = 0;
-    mHashResult.clear();
-  }
-  return success;
+       if(!m_initialized)
+       {
+               qWarning("QKeccakHash has not been initialized yet!");
+               return false;
+       }
+       
+       if(KeccakImpl::Update(m_state, (KeccakImpl::BitSequence*)data, size*8) != KeccakImpl::SUCCESS)
+       {
+               qWarning("KeccakImpl::Update() has failed unexpectedly!");
+               m_hashResult.clear();
+               m_initialized = false;
+               return false;
+       }
+       
+       return true;
 }
 
-bool QKeccakHash::stopBatch()
+const QByteArray &QKeccakHash::finalize()
 {
-  if (!isBatchRunning() || mHashBitLength == 0)
-    return false;
-  bool success = KeccakImpl::Final(mState, (KeccakImpl::BitSequence*)mHashResult.data()) == KeccakImpl::SUCCESS;
-  delete mState;
-  mState = 0;
-  if (!success)
-    mHashResult.clear();
-  return success;
+       if(!m_initialized)
+       {
+               qWarning("QKeccakHash has not been initialized yet!");
+               m_hashResult.clear();
+               return m_hashResult;
+       }
+
+       if(KeccakImpl::Final(m_state, (KeccakImpl::BitSequence*)m_hashResult.data()) != KeccakImpl::SUCCESS)
+       {
+               qWarning("KeccakImpl::Final() has failed unexpectedly!");
+               m_hashResult.clear();
+       }
+
+       m_initialized = false;
+       return m_hashResult;
 }
 
-bool QKeccakHash::isBatchRunning() const
+bool QKeccakHash::selfTest(void)
 {
-  return mState;
+       QKeccakHash hash;
+       const QByteArray input("The quick brown fox jumps over the lazy dog");
+       bool passed[4] = {false, false, false, false};
+
+       if(hash.init(QKeccakHash::hb224))
+       {
+               if(hash.addData(input))
+               {
+                       QByteArray result = hash.finalize();
+                       if(!result.isEmpty())
+                       {
+                               passed[0] = (_stricmp(result.toHex().constData(), "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe") == 0);
+                               if(!passed[0]) qWarning("QKeccakHash self-test: Test #1 failed !!!");
+                       }
+               }
+       }
+
+       if(hash.init(QKeccakHash::hb256))
+       {
+               if(hash.addData(input))
+               {
+                       QByteArray result = hash.finalize();
+                       if(!result.isEmpty())
+                       {
+                               passed[1] = (_stricmp(result.toHex().constData(), "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15") == 0);
+                               if(!passed[1]) qWarning("QKeccakHash self-test: Test #2 failed !!!");
+                       }
+               }
+       }
+       
+       if(hash.init(QKeccakHash::hb384))
+       {
+               if(hash.addData(input))
+               {
+                       QByteArray result = hash.finalize();
+                       if(!result.isEmpty())
+                       {
+                               passed[2] = (_stricmp(result.toHex().constData(), "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3") == 0);
+                               if(!passed[2]) qWarning("QKeccakHash self-test: Test #3 failed !!!");
+                       }
+               }
+       }
+
+       if(hash.init(QKeccakHash::hb512))
+       {
+               if(hash.addData(input))
+               {
+                       QByteArray result = hash.finalize();
+                       if(!result.isEmpty())
+                       {
+                               passed[3] = (_stricmp(result.toHex().constData(), "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609") == 0);
+                               if(!passed[3]) qWarning("QKeccakHash self-test: Test #4 failed !!!");
+                       }
+               }
+       }
+
+       return (passed[0] && passed[1] && passed[2] && passed[3]);
 }
-
-bool QKeccakHash::setHashBitLength(HashBits hashBits)
-{
-  switch (hashBits)
-  {
-    case hb224: mHashBitLength = 224; break;
-    case hb256: mHashBitLength = 256; break;
-    case hb384: mHashBitLength = 384; break;
-    case hb512: mHashBitLength = 512; break;
-    default: 
-    {
-      mHashBitLength = 0;
-      qDebug() << "QKeccakHash::setHashBitLength(): invalid hash bit value" << (int)hashBits << ", must be hb224, hb256, hb384 or hb512";
-      return false;
-    }
-  }
-  mHashResult.fill(0, mHashBitLength/8);
-  return true;
-}
-
index 7e71d1c..df5c41f 100644 (file)
 // Section from KeccakSponge.h
 // needed here, since hashState needs to be explicitly 32-byte aligned and therefore can't be
 // transformed into a class (in order to forward declarate) like in the other hash wrappers.
-namespace KeccakImpl {
-#define KeccakPermutationSize 1600
-#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
-#define KeccakMaximumRate 1536
-#define KeccakMaximumRateInBytes (KeccakMaximumRate/8)
+namespace KeccakImpl
+{
+       #define KeccakPermutationSize 1600
+       #define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
+       #define KeccakMaximumRate 1536
+       #define KeccakMaximumRateInBytes (KeccakMaximumRate/8)
 
-#if defined(__GNUC__)
-#define ALIGN __attribute__ ((aligned(32)))
-#elif defined(_MSC_VER)
-#define ALIGN __declspec(align(32))
-#else
-#define ALIGN
-#endif
+       #if defined(__GNUC__)
+       #define ALIGN __attribute__ ((aligned(32)))
+       #elif defined(_MSC_VER)
+       #define ALIGN __declspec(align(32))
+       #else
+       #define ALIGN
+       #endif
 
-ALIGN typedef struct spongeStateStruct {
-    ALIGN unsigned char state[KeccakPermutationSizeInBytes];
-    ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes];
-    unsigned int rate;
-    unsigned int capacity;
-    unsigned int bitsInQueue;
-    unsigned int fixedOutputLength;
-    int squeezing;
-    unsigned int bitsAvailableForSqueezing;
-} spongeState;
-typedef spongeState hashState;
+       ALIGN typedef struct spongeStateStruct {
+               ALIGN unsigned char state[KeccakPermutationSizeInBytes];
+               ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes];
+               unsigned int rate;
+               unsigned int capacity;
+               unsigned int bitsInQueue;
+               unsigned int fixedOutputLength;
+               int squeezing;
+               unsigned int bitsAvailableForSqueezing;
+       } spongeState;
+       typedef spongeState hashState;
 }
 // End Section from KeccakSponge.h
 
 class QKeccakHash
 {
 public:
-  enum HashBits {hb224, hb256, hb384, hb512};
-  QKeccakHash();
-  QKeccakHash(const QString &asciiMessage, HashBits hashBits=hb256);
-  ~QKeccakHash();
-  QByteArray toRaw() const;
-  QByteArray toHex() const;
-  QString toHexString() const;
-  bool file(const QString &fileName, HashBits hashBits=hb256, int blockSize=8388608); // 8 KiB default blockSize
-  bool startBatch(HashBits hashBits=hb256);
-  bool putBatch(const QByteArray &ba);
-  bool putBatch(const char *data, int size);
-  bool stopBatch();
-  bool isBatchRunning() const;
+       enum HashBits {hb224, hb256, hb384, hb512};
+       
+       QKeccakHash();
+       ~QKeccakHash();
+       
+       static bool selfTest(void);
+
+       bool init(HashBits hashBits=hb256);
+       bool addData(const QByteArray &data);
+       bool addData(const char *data, int size);
+       const QByteArray &finalize();
+
 protected:
-  bool setHashBitLength(HashBits hashBits);
-  KeccakImpl::hashState *mState;
-  QByteArray mHashResult;
-  int mHashBitLength;
+       bool m_initialized;
+       KeccakImpl::hashState *m_state;
+       QByteArray m_hashResult;
 };
 
 #endif // QKECCAKHASH_H
index 39e827c..805b0e4 100644 (file)
@@ -30,7 +30,7 @@
 #define VER_LAMEXP_MINOR_LO                                    7
 #define VER_LAMEXP_TYPE                                                Alpha
 #define VER_LAMEXP_PATCH                                       4
-#define VER_LAMEXP_BUILD                                       1197
+#define VER_LAMEXP_BUILD                                       1198
 
 ///////////////////////////////////////////////////////////////////////////////
 // Tool versions (minimum expected versions!)
index bb78d8d..3373d95 100644 (file)
@@ -63,22 +63,20 @@ static QByteArray fileHash(QFile &file)
        {
                QKeccakHash keccak;
 
-               QByteArray data = file.readAll();
-               QByteArray seed = QByteArray::fromHex(g_seed);
-               QByteArray salt = QByteArray::fromHex(g_salt);
+               const QByteArray data = file.readAll();
+               const QByteArray seed = QByteArray::fromHex(g_seed);
+               const QByteArray salt = QByteArray::fromHex(g_salt);
        
-               if(keccak.startBatch(QKeccakHash::hb384))
+               if(keccak.init(QKeccakHash::hb384))
                {
-                       bool ok[3];
-                       ok[0] = keccak.putBatch(seed);
-                       ok[1] = keccak.putBatch(data);
-                       ok[2] = keccak.putBatch(salt);
-                       if(ok[0] && ok[1] && ok[2])
+                       bool ok = true;
+                       ok = ok && keccak.addData(seed);
+                       ok = ok && keccak.addData(data);
+                       ok = ok && keccak.addData(salt);
+                       if(ok)
                        {
-                               if(keccak.stopBatch())
-                               {
-                                       hash = keccak.toHex();
-                               }
+                               const QByteArray digest = keccak.finalize();
+                               if(!digest.isEmpty()) hash = digest.toHex();
                        }
                }
        }
@@ -223,4 +221,12 @@ LockedFile::~LockedFile(void)
 const QString &LockedFile::filePath()
 {
        return m_filePath;
-}
\ No newline at end of file
+}
+
+void LockedFile::selfTest()
+{
+       if(!QKeccakHash::selfTest())
+       {
+               qFatal("QKeccakHash self-test has failed!");
+       }
+}
index 0367df7..c728237 100644 (file)
@@ -32,6 +32,8 @@ public:
 
        const QString &filePath();
 
+       static void selfTest();
+
 private:
        QString m_filePath;
        void *m_fileHandle;
index b2fa4d4..99a03ac 100644 (file)
@@ -217,6 +217,7 @@ void InitializationThread::run()
                pool->setMaxThreadCount(idealThreadCount * 2);
        }
        
+       LockedFile::selfTest();
        ExtractorTask::clearFlags();
 
        QTime timer;