1 /***************************************************************************
3 ** QKeccakHash, an API wrapper bringing the optimized implementation of **
4 ** Keccak (http://keccak.noekeon.org/) to Qt. **
5 ** Copyright (C) 2012 Emanuel Eichhammer **
7 ** This program is free software: you can redistribute it and/or modify **
8 ** it under the terms of the GNU General Public License as published by **
9 ** the Free Software Foundation, either version 3 of the License, or **
10 ** (at your option) any later version. **
12 ** This program is distributed in the hope that it will be useful, **
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of **
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
15 ** GNU General Public License for more details. **
17 ** You should have received a copy of the GNU General Public License **
18 ** along with this program. If not, see http://www.gnu.org/licenses/. **
20 ****************************************************************************
21 ** Author: Emanuel Eichhammer **
22 ** Website/Contact: http://www.WorksLikeClockwork.com/ **
24 ****************************************************************************/
26 #include "qkeccakhash.h"
29 #include "keccakimpl.cpp"
31 QKeccakHash::QKeccakHash()
33 m_initialized = false;
34 m_state = new KeccakImpl::hashState;
35 memset(m_state, 0, sizeof(KeccakImpl::hashState));
39 QKeccakHash::~QKeccakHash()
50 bool QKeccakHash::init(HashBits hashBits)
54 qWarning("QKeccakHash has already been initialized!");
59 memset(m_state, 0, sizeof(KeccakImpl::hashState));
60 int hashBitLength = 0;
64 case hb224: hashBitLength = 224; break;
65 case hb256: hashBitLength = 256; break;
66 case hb384: hashBitLength = 384; break;
67 case hb512: hashBitLength = 512; break;
68 default: throw "Invalid hash length!!";
71 if(KeccakImpl::Init(m_state, hashBitLength) != KeccakImpl::SUCCESS)
73 qWarning("KeccakImpl::Init() has failed unexpectedly!");
77 m_hashResult.fill(char(0), hashBitLength/8);
83 bool QKeccakHash::addData(const QByteArray &data)
85 return addData(data.constData(), data.size());
88 bool QKeccakHash::addData(const char *data, int size)
92 qWarning("QKeccakHash has not been initialized yet!");
96 if(KeccakImpl::Update(m_state, (KeccakImpl::BitSequence*)data, size*8) != KeccakImpl::SUCCESS)
98 qWarning("KeccakImpl::Update() has failed unexpectedly!");
100 m_initialized = false;
107 const QByteArray &QKeccakHash::finalize()
111 qWarning("QKeccakHash has not been initialized yet!");
112 m_hashResult.clear();
116 if(KeccakImpl::Final(m_state, (KeccakImpl::BitSequence*)m_hashResult.data()) != KeccakImpl::SUCCESS)
118 qWarning("KeccakImpl::Final() has failed unexpectedly!");
119 m_hashResult.clear();
122 m_initialized = false;
126 bool QKeccakHash::selfTest(void)
129 const QByteArray input("The quick brown fox jumps over the lazy dog");
130 bool passed[4] = {false, false, false, false};
132 if(hash.init(QKeccakHash::hb224))
134 if(hash.addData(input))
136 QByteArray result = hash.finalize();
137 if(!result.isEmpty())
139 passed[0] = (_stricmp(result.toHex().constData(), "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe") == 0);
140 if(!passed[0]) qWarning("QKeccakHash self-test: Test #1 failed !!!");
145 if(hash.init(QKeccakHash::hb256))
147 if(hash.addData(input))
149 QByteArray result = hash.finalize();
150 if(!result.isEmpty())
152 passed[1] = (_stricmp(result.toHex().constData(), "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15") == 0);
153 if(!passed[1]) qWarning("QKeccakHash self-test: Test #2 failed !!!");
158 if(hash.init(QKeccakHash::hb384))
160 if(hash.addData(input))
162 QByteArray result = hash.finalize();
163 if(!result.isEmpty())
165 passed[2] = (_stricmp(result.toHex().constData(), "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3") == 0);
166 if(!passed[2]) qWarning("QKeccakHash self-test: Test #3 failed !!!");
171 if(hash.init(QKeccakHash::hb512))
173 if(hash.addData(input))
175 QByteArray result = hash.finalize();
176 if(!result.isEmpty())
178 passed[3] = (_stricmp(result.toHex().constData(), "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609") == 0);
179 if(!passed[3]) qWarning("QKeccakHash self-test: Test #4 failed !!!");
184 return (passed[0] && passed[1] && passed[2] && passed[3]);