Happy new year 2015 !!!
[MUtilities.git] / src / KeccakHash.cpp
blob6962a494d078f145825b6023e50d8b5f77e69451
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
22 /***************************************************************************
23 ** **
24 ** QKeccakHash, an API wrapper bringing the optimized implementation of **
25 ** Keccak (http://keccak.noekeon.org/) to Qt. **
26 ** Copyright (C) 2013 Emanuel Eichhammer **
27 ** **
28 ** This program is free software: you can redistribute it and/or modify **
29 ** it under the terms of the GNU General Public License as published by **
30 ** the Free Software Foundation, either version 3 of the License, or **
31 ** (at your option) any later version. **
32 ** **
33 ** This program is distributed in the hope that it will be useful, **
34 ** but WITHOUT ANY WARRANTY; without even the implied warranty of **
35 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
36 ** GNU General Public License for more details. **
37 ** **
38 ** You should have received a copy of the GNU General Public License **
39 ** along with this program. If not, see http://www.gnu.org/licenses/. **
40 ** **
41 ****************************************************************************
42 ** Author: Emanuel Eichhammer **
43 ** Website/Contact: http://www.WorksLikeClockwork.com/ **
44 ** Date: 12.01.12 **
45 ****************************************************************************/
47 #include <MUtils/KeccakHash.h>
48 #include <QDebug>
50 #include "3rd_party/keccak/include/keccak_impl.h"
52 MUtils::KeccakHash::KeccakHash()
54 m_initialized = false;
55 m_state = (MUtils::Internal::KeccakImpl::hashState*) _aligned_malloc(sizeof(MUtils::Internal::KeccakImpl::hashState), 32);
56 if(!m_state)
58 throw "[MUtils::KeccakHash] Error: _aligned_malloc() has failed, probably out of heap space!";
60 memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState));
61 m_hashResult.clear();
64 MUtils::KeccakHash::~KeccakHash()
66 m_hashResult.clear();
68 if(m_state)
70 _aligned_free(m_state);
71 m_state = NULL;
75 bool MUtils::KeccakHash::init(HashBits hashBits)
77 if(m_initialized)
79 qWarning("MUtils::KeccakHash has already been initialized!");
80 return false;
83 m_hashResult.clear();
84 memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState));
85 int hashBitLength = 0;
87 switch (hashBits)
89 case hb224: hashBitLength = 224; break;
90 case hb256: hashBitLength = 256; break;
91 case hb384: hashBitLength = 384; break;
92 case hb512: hashBitLength = 512; break;
93 default: throw "Invalid hash length!!";
96 if(MUtils::Internal::KeccakImpl::Init(m_state, hashBitLength) != MUtils::Internal::KeccakImpl::SUCCESS)
98 qWarning("KeccakImpl::Init() has failed unexpectedly!");
99 return false;
102 m_hashResult.fill(char(0), hashBitLength/8);
103 m_initialized = true;
105 return true;
108 bool MUtils::KeccakHash::addData(const QByteArray &data)
110 return addData(data.constData(), data.size());
113 bool MUtils::KeccakHash::addData(const char *data, int size)
115 if(!m_initialized)
117 qWarning("MUtils::KeccakHash has not been initialized yet!");
118 return false;
121 if(MUtils::Internal::KeccakImpl::Update(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)data, size*8) != MUtils::Internal::KeccakImpl::SUCCESS)
123 qWarning("KeccakImpl::Update() has failed unexpectedly!");
124 m_hashResult.clear();
125 m_initialized = false;
126 return false;
129 return true;
132 const QByteArray &MUtils::KeccakHash::finalize()
134 if(!m_initialized)
136 qWarning("MUtils::KeccakHash has not been initialized yet!");
137 m_hashResult.clear();
138 return m_hashResult;
141 if(MUtils::Internal::KeccakImpl::Final(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)m_hashResult.data()) != MUtils::Internal::KeccakImpl::SUCCESS)
143 qWarning("KeccakImpl::Final() has failed unexpectedly!");
144 m_hashResult.clear();
147 m_initialized = false;
148 return m_hashResult;
151 bool MUtils::KeccakHash::selfTest(void)
153 MUtils::KeccakHash hash;
154 const QByteArray input("The quick brown fox jumps over the lazy dog");
155 bool passed[4] = {false, false, false, false};
157 if(hash.init(MUtils::KeccakHash::hb224))
159 if(hash.addData(input))
161 QByteArray result = hash.finalize();
162 if(!result.isEmpty())
164 passed[0] = (_stricmp(result.toHex().constData(), "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe") == 0);
165 if(!passed[0]) qWarning("MUtils::KeccakHash self-test: Test #1 failed !!!");
170 if(hash.init(MUtils::KeccakHash::hb256))
172 if(hash.addData(input))
174 QByteArray result = hash.finalize();
175 if(!result.isEmpty())
177 passed[1] = (_stricmp(result.toHex().constData(), "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15") == 0);
178 if(!passed[1]) qWarning("MUtils::KeccakHash self-test: Test #2 failed !!!");
183 if(hash.init(MUtils::KeccakHash::hb384))
185 if(hash.addData(input))
187 QByteArray result = hash.finalize();
188 if(!result.isEmpty())
190 passed[2] = (_stricmp(result.toHex().constData(), "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3") == 0);
191 if(!passed[2]) qWarning("MUtils::KeccakHash self-test: Test #3 failed !!!");
196 if(hash.init(MUtils::KeccakHash::hb512))
198 if(hash.addData(input))
200 QByteArray result = hash.finalize();
201 if(!result.isEmpty())
203 passed[3] = (_stricmp(result.toHex().constData(), "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609") == 0);
204 if(!passed[3]) qWarning("MUtils::KeccakHash self-test: Test #4 failed !!!");
209 return (passed[0] && passed[1] && passed[2] && passed[3]);