1/**
2 * Copyright (C) 2004-2006 Brad Hards <bradh@frogmouth.net>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include <QFile>
27#include <QtCrypto>
28#include <QtTest/QtTest>
29
30#ifdef QT_STATICPLUGIN
31#include "import_plugins.h"
32#endif
33
34class HashUnitTest : public QObject
35{
36 Q_OBJECT
37
38private Q_SLOTS:
39 void initTestCase();
40 void cleanupTestCase();
41 void md2test_data();
42 void md2test();
43 void md4test_data();
44 void md4test();
45 void md5test_data();
46 void md5test();
47 void md5filetest();
48 void sha0test_data();
49 void sha0test();
50 void sha0longtest();
51 void sha1test_data();
52 void sha1test();
53 void sha1longtest();
54 void sha224test_data();
55 void sha224test();
56 void sha224longtest();
57 void sha256test_data();
58 void sha256test();
59 void sha256longtest();
60 void sha384test_data();
61 void sha384test();
62 void sha384longtest();
63 void sha512test_data();
64 void sha512test();
65 void sha512longtest();
66 void rmd160test_data();
67 void rmd160test();
68 void rmd160longtest();
69 void whirlpooltest_data();
70 void whirlpooltest();
71 void whirlpoollongtest();
72
73private:
74 QCA::Initializer *m_init;
75 QStringList providersToTest;
76};
77
78void HashUnitTest::initTestCase()
79{
80 m_init = new QCA::Initializer;
81 const auto providers = QCA::providers();
82 for (QCA::Provider *provider : providers)
83 providersToTest << provider->name();
84 providersToTest << QCA::defaultProvider()->name();
85}
86
87void HashUnitTest::cleanupTestCase()
88{
89 QCA::unloadAllPlugins();
90 delete m_init;
91}
92
93void HashUnitTest::md2test_data()
94{
95 // These are as specified in RFC 1319
96 QTest::addColumn<QByteArray>(name: "input");
97 QTest::addColumn<QString>(name: "expectedHash");
98
99 QTest::newRow(dataTag: "md2()") << QByteArray("") << QStringLiteral("8350e5a3e24c153df2275c9f80692773");
100 QTest::newRow(dataTag: "md2(a)") << QByteArray("a") << QStringLiteral("32ec01ec4a6dac72c0ab96fb34c0b5d1");
101 QTest::newRow(dataTag: "md2(abc)") << QByteArray("abc") << QStringLiteral("da853b0d3f88d99b30283a69e6ded6bb");
102 QTest::newRow(dataTag: "md2(messageDigest)") << QByteArray("message digest")
103 << QStringLiteral("ab4f496bfb2a530b219ff33031fe06b0");
104 QTest::newRow(dataTag: "md2([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
105 << QStringLiteral("4e8ddff3650292ab5a4108c3aa47940b");
106 QTest::newRow(dataTag: "md2([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
107 << QStringLiteral("da33def2a42df13975352846c30338cd");
108 QTest::newRow(dataTag: "md2(nums)")
109 << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
110 << QStringLiteral("d5976f79d83d3a0dc9806c3c66f3efd8");
111}
112
113void HashUnitTest::md2test()
114{
115 QFETCH(QByteArray, input);
116 QFETCH(QString, expectedHash);
117
118 bool anyProviderTested = false;
119 foreach (QString provider, providersToTest) {
120 if (QCA::isSupported(features: "md2", provider)) {
121 anyProviderTested = true;
122
123 QCA::Hash hash = QCA::Hash(QStringLiteral("md2"), provider);
124 QCA::Hash copy = hash;
125 copy.context(); // detach
126
127 QCOMPARE(hash.hashToString(input), expectedHash);
128 QCOMPARE(copy.hashToString(input), expectedHash);
129 }
130 }
131 if (!anyProviderTested)
132 qWarning() << "NONE of the providers supports MD2:" << providersToTest;
133}
134
135void HashUnitTest::md4test_data()
136{
137 // These are as specified in RFC 1320
138 QTest::addColumn<QByteArray>(name: "input");
139 QTest::addColumn<QString>(name: "expectedHash");
140
141 QTest::newRow(dataTag: "md4()") << QByteArray("") << QStringLiteral("31d6cfe0d16ae931b73c59d7e0c089c0");
142 QTest::newRow(dataTag: "md4(a)") << QByteArray("a") << QStringLiteral("bde52cb31de33e46245e05fbdbd6fb24");
143 QTest::newRow(dataTag: "md4(abc)") << QByteArray("abc") << QStringLiteral("a448017aaf21d8525fc10ae87aa6729d");
144 QTest::newRow(dataTag: "md4(messageDigest)") << QByteArray("message digest")
145 << QStringLiteral("d9130a8164549fe818874806e1c7014b");
146 QTest::newRow(dataTag: "md4([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
147 << QStringLiteral("d79e1c308aa5bbcdeea8ed63df412da9");
148 QTest::newRow(dataTag: "md4([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
149 << QStringLiteral("043f8582f241db351ce627e153e7f0e4");
150 QTest::newRow(dataTag: "md4(nums)")
151 << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
152 << QStringLiteral("e33b4ddc9c38f2199c3e7b164fcc0536");
153}
154
155void HashUnitTest::md4test()
156{
157 bool anyProviderTested = false;
158 QFETCH(QByteArray, input);
159 QFETCH(QString, expectedHash);
160
161 foreach (QString provider, providersToTest) {
162 if (QCA::isSupported(features: "md4", provider)) {
163 anyProviderTested = true;
164
165 QCA::Hash hash = QCA::Hash(QStringLiteral("md4"), provider);
166 QCA::Hash copy = hash;
167 hash.context(); // detach
168
169 QCOMPARE(hash.hashToString(input), expectedHash);
170 QCOMPARE(copy.hashToString(input), expectedHash);
171 }
172 }
173 if (!anyProviderTested)
174 qWarning() << "NONE of the providers supports MD4:" << providersToTest;
175}
176
177void HashUnitTest::md5test_data()
178{
179 // These are as specified in RFC 1321
180 // They also match Australian Standard (AS) 2805.1.3.2-2000 Appendix A
181 QTest::addColumn<QByteArray>(name: "input");
182 QTest::addColumn<QString>(name: "expectedHash");
183
184 QTest::newRow(dataTag: "md5()") << QByteArray("") << QStringLiteral("d41d8cd98f00b204e9800998ecf8427e");
185 QTest::newRow(dataTag: "md5(a)") << QByteArray("a") << QStringLiteral("0cc175b9c0f1b6a831c399e269772661");
186 QTest::newRow(dataTag: "md5(abc)") << QByteArray("abc") << QStringLiteral("900150983cd24fb0d6963f7d28e17f72");
187 QTest::newRow(dataTag: "md5(messageDigest)") << QByteArray("message digest")
188 << QStringLiteral("f96b697d7cb7938d525a2f31aaf161d0");
189 QTest::newRow(dataTag: "md5([a-z])") << QByteArray("abcdefghijklmnopqrstuvwxyz")
190 << QStringLiteral("c3fcd3d76192e4007dfb496cca67e13b");
191 QTest::newRow(dataTag: "md5([A-z,0-9])") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
192 << QStringLiteral("d174ab98d277d9f5a5611c2c9f419d9f");
193 QTest::newRow(dataTag: "md5(nums)")
194 << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
195 << QStringLiteral("57edf4a22be3c955ac49da2e2107b67a");
196}
197
198void HashUnitTest::md5test()
199{
200 bool anyProviderTested = false;
201 QFETCH(QByteArray, input);
202 QFETCH(QString, expectedHash);
203
204 foreach (QString provider, providersToTest) {
205 if (QCA::isSupported(features: "md5", provider)) {
206 anyProviderTested = true;
207
208 QCA::Hash hash = QCA::Hash(QStringLiteral("md5"), provider);
209 QCA::Hash copy = hash;
210 hash.context(); // detach
211
212 QCOMPARE(hash.hashToString(input), expectedHash);
213 QCOMPARE(copy.hashToString(input), expectedHash);
214 }
215 }
216 if (!anyProviderTested)
217 qWarning() << "NONE of the providers supports MD2:" << providersToTest;
218}
219
220void HashUnitTest::md5filetest()
221{
222 foreach (QString provider, providersToTest) {
223 if (!QCA::isSupported(features: "md5", provider)) {
224 QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty"));
225 QVERIFY(f1.open(QIODevice::ReadOnly));
226 {
227 QCA::Hash hashObj(QStringLiteral("md5"), provider);
228 hashObj.update(file: &f1);
229 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
230 QStringLiteral("d41d8cd98f00b204e9800998ecf8427e"));
231 }
232
233 QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes"));
234 QVERIFY(f2.open(QIODevice::ReadOnly));
235 {
236 QCA::Hash hashObj(QStringLiteral("md5"), provider);
237 hashObj.update(file: &f2);
238 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
239 QStringLiteral("5fc9808ed18e442ab4164c59f151e757"));
240 }
241
242 QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes"));
243 QVERIFY(f3.open(QIODevice::ReadOnly));
244 {
245 QCA::Hash hashObj(QStringLiteral("md5"), provider);
246 hashObj.update(file: &f3);
247 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
248 QStringLiteral("b91c1f114d942520ecdf7e84e580cda3"));
249 }
250 }
251 }
252}
253
254void HashUnitTest::sha0test_data()
255{
256 // These are extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
257 // Check FIPS 180-1?
258 QTest::addColumn<QByteArray>(name: "input");
259 QTest::addColumn<QString>(name: "expectedHash");
260
261 QTest::newRow(dataTag: "sha0(abc)") << QByteArray("abc") << QStringLiteral("0164b8a914cd2a5e74c4f7ff082c4d97f1edf880");
262 QTest::newRow(dataTag: "sha0(abc)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
263 << QStringLiteral("d2516ee1acfa5baf33dfc1c471e438449ef134c8");
264}
265
266void HashUnitTest::sha0test()
267{
268 bool anyProviderTested = false;
269 QFETCH(QByteArray, input);
270 QFETCH(QString, expectedHash);
271
272 foreach (QString provider, providersToTest) {
273 if (QCA::isSupported(features: "sha0", provider)) {
274 anyProviderTested = true;
275
276 QCA::Hash hash = QCA::Hash(QStringLiteral("sha0"), provider);
277 QCA::Hash copy = hash;
278 hash.context(); // detach
279
280 QCOMPARE(hash.hashToString(input), expectedHash);
281 QCOMPARE(copy.hashToString(input), expectedHash);
282 }
283 }
284 if (!anyProviderTested)
285 qWarning() << "NONE of the providers supports SHA0:" << providersToTest;
286}
287
288void HashUnitTest::sha0longtest()
289{
290 QByteArray fillerString;
291 fillerString.fill(c: 'a', size: 1000);
292
293 // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
294
295 foreach (QString provider, providersToTest) {
296 if (QCA::isSupported(features: "sha0", provider)) {
297 QCA::Hash shaHash(QStringLiteral("sha0"), provider);
298 for (int i = 0; i < 1000; i++)
299 shaHash.update(a: fillerString);
300 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
301 QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603"));
302
303 shaHash.clear();
304 for (int i = 0; i < 1000; i++)
305 shaHash.update(a: fillerString);
306 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
307 QStringLiteral("3232affa48628a26653b5aaa44541fd90d690603"));
308 }
309 }
310}
311
312void HashUnitTest::sha1test_data()
313{
314 // These are as specified in FIPS 180-2. Matches RFC3174
315 // Some additions from Australian Standard (AS) 2805.13.3-2000
316 QTest::addColumn<QByteArray>(name: "input");
317 QTest::addColumn<QString>(name: "expectedHash");
318
319 // FIPS 180-2, Appendix A.1
320 QTest::newRow(dataTag: "sha1(abc)") << QByteArray("abc") << QStringLiteral("a9993e364706816aba3e25717850c26c9cd0d89d");
321
322 // FIPS 180-2, Appendix A.2
323 QTest::newRow(dataTag: "sha1(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
324 << QStringLiteral("84983e441c3bd26ebaae4aa1f95129e5e54670f1");
325
326 // AS 2805.13.3-200 Appendix A
327 // also has some duplicates from FIPS 180-2
328 QTest::newRow(dataTag: "sha1()") << QByteArray("") << QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709");
329 QTest::newRow(dataTag: "sha1(a)") << QByteArray("a") << QStringLiteral("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
330 QTest::newRow(dataTag: "sha1(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
331 << QStringLiteral("32d10c7b8cf96570ca04ce37f2a19d84240d3a89");
332}
333
334void HashUnitTest::sha1test()
335{
336 bool anyProviderTested = false;
337 QFETCH(QByteArray, input);
338 QFETCH(QString, expectedHash);
339
340 foreach (QString provider, providersToTest) {
341 if (QCA::isSupported(features: "sha1", provider)) {
342 anyProviderTested = true;
343
344 QCA::Hash hash = QCA::Hash(QStringLiteral("sha1"), provider);
345 QCA::Hash copy = hash;
346 hash.context(); // detach
347
348 QCOMPARE(hash.hashToString(input), expectedHash);
349 QCOMPARE(copy.hashToString(input), expectedHash);
350 }
351 }
352 if (!anyProviderTested)
353 qWarning() << "NONE of the providers supports SHA1:" << providersToTest;
354}
355
356void HashUnitTest::sha1longtest()
357{
358 foreach (QString provider, providersToTest) {
359 if (QCA::isSupported(features: "sha1", provider)) {
360 // QTime t;
361 // t.start();
362 QByteArray fillerString;
363 fillerString.fill(c: 'a', size: 1000);
364
365 // This test extracted from OpenOffice.org 1.1.2, in sal/workben/t_digest.c
366 // It basically reflects FIPS 180-2, Appendix A.3
367 // Also as per AS 2805.13.3-2000 Appendix A
368 QCA::Hash shaHash(QStringLiteral("sha1"), provider);
369 for (int i = 0; i < 1000; i++)
370 shaHash.update(a: fillerString);
371 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
372 QStringLiteral("34aa973cd4c4daa4f61eeb2bdbad27316534016f"));
373
374 QFile f1(QStringLiteral(TEST_DATA_DIR "/data/empty"));
375 QVERIFY(f1.open(QIODevice::ReadOnly));
376 {
377 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
378 hashObj.update(file: &f1);
379 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
380 QStringLiteral("da39a3ee5e6b4b0d3255bfef95601890afd80709"));
381 }
382
383 QFile f2(QStringLiteral(TEST_DATA_DIR "/data/twobytes"));
384 QVERIFY(f2.open(QIODevice::ReadOnly));
385 {
386 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
387 hashObj.update(file: &f2);
388 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
389 QStringLiteral("efbd6de3c51ca16094391e837bf52f7452593e5c"));
390 }
391
392 QFile f3(QStringLiteral(TEST_DATA_DIR "/data/twohundredbytes"));
393 QVERIFY(f3.open(QIODevice::ReadOnly));
394 {
395 QCA::Hash hashObj(QStringLiteral("sha1"), provider);
396 hashObj.update(file: &f3);
397 QCOMPARE(QString(QCA::arrayToHex(hashObj.final().toByteArray())),
398 QStringLiteral("d636519dfb18d913acbe69fc3ee5a4c7ac870297"));
399 }
400 }
401 }
402}
403
404void HashUnitTest::sha224test_data()
405{
406 QTest::addColumn<QByteArray>(name: "input");
407 QTest::addColumn<QString>(name: "expectedHash");
408
409 // These are as specified in FIPS 180-2, change notice 1
410
411 // FIPS 180-2, Appendix B.1
412 QTest::newRow(dataTag: "sha224(abc)") << QByteArray("abc")
413 << QStringLiteral("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7");
414
415 // FIPS 180-2, Appendix B.2
416 QTest::newRow(dataTag: "sha224(aq)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
417 << QStringLiteral("75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525");
418}
419
420void HashUnitTest::sha224test()
421{
422 bool anyProviderTested = false;
423 QFETCH(QByteArray, input);
424 QFETCH(QString, expectedHash);
425
426 foreach (QString provider, providersToTest) {
427 if (QCA::isSupported(features: "sha224", provider)) {
428 anyProviderTested = true;
429
430 QCA::Hash hash = QCA::Hash(QStringLiteral("sha224"), provider);
431 QCA::Hash copy = hash;
432 hash.context(); // detach
433
434 QCOMPARE(hash.hashToString(input), expectedHash);
435 QCOMPARE(copy.hashToString(input), expectedHash);
436 }
437 }
438 if (!anyProviderTested)
439 qWarning() << "NONE of the providers supports SHA224:" << providersToTest;
440}
441
442void HashUnitTest::sha224longtest()
443{
444 QByteArray fillerString;
445 fillerString.fill(c: 'a', size: 1000);
446
447 foreach (QString provider, providersToTest) {
448 if (QCA::isSupported(features: "sha224", provider)) {
449 QCA::Hash shaHash(QStringLiteral("sha224"), provider);
450
451 // This basically reflects FIPS 180-2, change notice 1, section 3
452 for (int i = 0; i < 1000; i++)
453 shaHash.update(a: fillerString);
454 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
455 QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"));
456
457 shaHash.clear();
458 for (int i = 0; i < 1000; i++)
459 shaHash.update(a: fillerString);
460 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
461 QStringLiteral("20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"));
462 }
463 }
464}
465
466void HashUnitTest::sha256test_data()
467{
468 QTest::addColumn<QByteArray>(name: "input");
469 QTest::addColumn<QString>(name: "expectedHash");
470
471 // These are as specified in FIPS 180-2
472
473 // FIPS 180-2, Appendix B.1
474 QTest::newRow(dataTag: "sha256(abc)") << QByteArray("abc")
475 << QStringLiteral("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
476
477 // FIPS 180-2, Appendix B.2
478 QTest::newRow(dataTag: "sha256(abc)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
479 << QStringLiteral("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1");
480}
481
482void HashUnitTest::sha256test()
483{
484 bool anyProviderTested = false;
485 QFETCH(QByteArray, input);
486 QFETCH(QString, expectedHash);
487
488 foreach (QString provider, providersToTest) {
489 if (QCA::isSupported(features: "sha256", provider)) {
490 anyProviderTested = true;
491
492 QCA::Hash hash = QCA::Hash(QStringLiteral("sha256"), provider);
493 QCA::Hash copy = hash;
494 hash.context(); // detach
495
496 QCOMPARE(hash.hashToString(input), expectedHash);
497 QCOMPARE(copy.hashToString(input), expectedHash);
498 }
499 }
500 if (!anyProviderTested)
501 qWarning() << "NONE of the providers supports SHA256:" << providersToTest;
502}
503
504void HashUnitTest::sha256longtest()
505{
506 QByteArray fillerString;
507 fillerString.fill(c: 'a', size: 1000);
508
509 foreach (QString provider, providersToTest) {
510 if (QCA::isSupported(features: "sha256", provider)) {
511 QCA::Hash shaHash(QStringLiteral("sha256"), provider);
512
513 // This basically reflects FIPS 180-2, change notice 1, section 3
514 for (int i = 0; i < 1000; i++)
515 shaHash.update(a: fillerString);
516 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
517 QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"));
518
519 shaHash.clear();
520 for (int i = 0; i < 1000; i++)
521 shaHash.update(a: fillerString);
522 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
523 QStringLiteral("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"));
524 }
525 }
526}
527
528void HashUnitTest::sha384test_data()
529{
530 QTest::addColumn<QByteArray>(name: "input");
531 QTest::addColumn<QString>(name: "expectedHash");
532
533 // These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests
534
535 // FIPS 180-2, Appendix B.1
536 QTest::newRow(dataTag: "sha384(abc)")
537 << QByteArray("abc")
538 << QStringLiteral(
539 "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7");
540
541 // FIPS 180-2, Appendix B.2
542 QTest::newRow(dataTag: "sha384(a-u)")
543 << QByteArray(
544 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrs"
545 "tnopqrstu")
546 << QStringLiteral(
547 "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039");
548
549 // Aaron Gifford, vector002.info
550 QTest::newRow(dataTag: "sha384(a-q)")
551 << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
552 << QStringLiteral(
553 "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b");
554}
555
556void HashUnitTest::sha384test()
557{
558 bool anyProviderTested = false;
559 QFETCH(QByteArray, input);
560 QFETCH(QString, expectedHash);
561
562 foreach (QString provider, providersToTest) {
563 if (QCA::isSupported(features: "sha384", provider)) {
564 anyProviderTested = true;
565
566 QCA::Hash hash = QCA::Hash(QStringLiteral("sha384"), provider);
567 QCA::Hash copy = hash;
568 hash.context(); // detach
569
570 QCOMPARE(hash.hashToString(input), expectedHash);
571 QCOMPARE(copy.hashToString(input), expectedHash);
572 }
573 }
574 if (!anyProviderTested)
575 qWarning() << "NONE of the providers supports SHA384:" << providersToTest;
576}
577
578void HashUnitTest::sha384longtest()
579{
580 QByteArray fillerString;
581 fillerString.fill(c: 'a', size: 1000);
582
583 foreach (QString provider, providersToTest) {
584 if (QCA::isSupported(features: "sha384", provider)) {
585 // QTime t;
586 // t.start();
587 QCA::Hash shaHash(QStringLiteral("sha384"), provider);
588
589 // This basically reflects FIPS 180-2, change notice 1, section 3
590 for (int i = 0; i < 1000; i++)
591 shaHash.update(a: fillerString);
592 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
593 QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae"
594 "97ddd87f3d8985"));
595
596 shaHash.clear();
597 for (int i = 0; i < 1000; i++)
598 shaHash.update(a: fillerString);
599 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
600 QStringLiteral("9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae"
601 "97ddd87f3d8985"));
602 // qDebug() << "SHA384: " << provider << " elapsed " << t.elapsed();
603 }
604 }
605}
606
607// These are as specified in FIPS 180-2, and from Aaron Gifford's SHA2 tests
608void HashUnitTest::sha512test_data()
609{
610 QTest::addColumn<QByteArray>(name: "input");
611 QTest::addColumn<QString>(name: "expectedHash");
612
613 // FIPS 180-2, Appendix C.1
614 QTest::newRow(dataTag: "sha512(abc)") << QByteArray("abc")
615 << QStringLiteral(
616 "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1"
617 "a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f");
618 // FIPS 180-2, Appendix C.2
619 QTest::newRow(dataTag: "sha512(a-u)") << QByteArray(
620 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmno"
621 "pqklmnopqrlmnopqrsmnopqrstnopqrstu")
622 << QStringLiteral(
623 "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7"
624 "e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909");
625
626 // Aaron Gifford, vector002.info
627 QTest::newRow(dataTag: "sha512(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
628 << QStringLiteral(
629 "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07"
630 "f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445");
631}
632
633void HashUnitTest::sha512test()
634{
635 bool anyProviderTested = false;
636 QFETCH(QByteArray, input);
637 QFETCH(QString, expectedHash);
638
639 foreach (QString provider, providersToTest) {
640 if (QCA::isSupported(features: "sha512", provider)) {
641 anyProviderTested = true;
642
643 QCA::Hash hash = QCA::Hash(QStringLiteral("sha512"), provider);
644 QCA::Hash copy = hash;
645 hash.context(); // detach
646
647 QCOMPARE(hash.hashToString(input), expectedHash);
648 QCOMPARE(copy.hashToString(input), expectedHash);
649 }
650 }
651 if (!anyProviderTested)
652 qWarning() << "NONE of the providers supports SHA512:" << providersToTest;
653}
654
655void HashUnitTest::sha512longtest()
656{
657 QByteArray fillerString;
658 fillerString.fill(c: 'a', size: 1000);
659
660 foreach (QString provider, providersToTest) {
661 if (QCA::isSupported(features: "sha512", provider)) {
662 QCA::Hash shaHash(QStringLiteral("sha512"), provider);
663
664 // This basically reflects FIPS 180-2, change notice 1, section 3
665 for (int i = 0; i < 1000; i++)
666 shaHash.update(a: fillerString);
667 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
668 QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c"
669 "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"));
670
671 shaHash.clear();
672 for (int i = 0; i < 1000; i++)
673 shaHash.update(a: fillerString);
674 QCOMPARE(QString(QCA::arrayToHex(shaHash.final().toByteArray())),
675 QStringLiteral("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4c"
676 "b0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"));
677 }
678 }
679}
680
681// These are as specified in http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
682// ISO/IEC 10118-3 costs a bit of money.
683void HashUnitTest::rmd160test_data()
684{
685 QTest::addColumn<QByteArray>(name: "input");
686 QTest::addColumn<QString>(name: "expectedHash");
687
688 QTest::newRow(dataTag: "rmd160()") << QByteArray("") << QStringLiteral("9c1185a5c5e9fc54612808977ee8f548b2258d31");
689 QTest::newRow(dataTag: "rmd160(a)") << QByteArray("a") << QStringLiteral("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
690 QTest::newRow(dataTag: "rmd160(abc)") << QByteArray("abc") << QStringLiteral("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
691 QTest::newRow(dataTag: "rmd160(md)") << QByteArray("message digest")
692 << QStringLiteral("5d0689ef49d2fae572b881b123a85ffa21595f36");
693 QTest::newRow(dataTag: "rmd160(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
694 << QStringLiteral("f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
695 QTest::newRow(dataTag: "rmd160(a-q)") << QByteArray("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
696 << QStringLiteral("12a053384a9c0c88e405a06c27dcf49ada62eb2b");
697 QTest::newRow(dataTag: "rmd160(A-9)") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
698 << QStringLiteral("b0e20b6e3116640286ed3a87a5713079b21f5189");
699 QTest::newRow(dataTag: "rmd160(1-0)")
700 << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
701 << QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb");
702}
703
704void HashUnitTest::rmd160test()
705{
706 bool anyProviderTested = false;
707 QFETCH(QByteArray, input);
708 QFETCH(QString, expectedHash);
709
710 foreach (QString provider, providersToTest) {
711 if (QCA::isSupported(features: "ripemd160", provider)) {
712 anyProviderTested = true;
713
714 QCA::Hash hash = QCA::Hash(QStringLiteral("ripemd160"), provider);
715 QCA::Hash copy = hash;
716 hash.context(); // detach
717
718 QCOMPARE(hash.hashToString(input), expectedHash);
719 QCOMPARE(copy.hashToString(input), expectedHash);
720 }
721 }
722 if (!anyProviderTested)
723 qWarning() << "NONE of the providers supports RIPEMD160:" << providersToTest;
724}
725
726void HashUnitTest::rmd160longtest()
727{
728 QByteArray fillerString;
729 fillerString.fill(c: 'a', size: 1000);
730
731 foreach (QString provider, providersToTest) {
732 if (QCA::isSupported(features: "ripemd160", provider)) {
733 QCA::Hash rmdHash(QStringLiteral("ripemd160"), provider);
734
735 // This is the "million times 'a' test"
736 for (int i = 0; i < 1000; i++)
737 rmdHash.update(a: fillerString);
738 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
739 QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528"));
740
741 rmdHash.clear();
742 for (int i = 0; i < 1000; i++)
743 rmdHash.update(a: fillerString);
744 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
745 QStringLiteral("52783243c1697bdbe16d37f97f68f08325dc1528"));
746
747 // This is the "8 rounds of 1234567890" test.
748 // It also ensure that we can re-use hash objects correctly.
749 static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
750 QByteArray fillerArray(bindata, sizeof(bindata)); // "1234567890"
751 rmdHash.clear();
752 for (int i = 0; i < 8; i++)
753 rmdHash.update(a: fillerArray);
754 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
755 QStringLiteral("9b752e45573d4b39f4dbd3323cab82bf63326bfb"));
756 }
757 }
758}
759
760// These are from the documentation pack at http://paginas.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html
761void HashUnitTest::whirlpooltest_data()
762{
763 QTest::addColumn<QByteArray>(name: "input");
764 QTest::addColumn<QString>(name: "expectedHash");
765
766 QTest::newRow(dataTag: "whirlpool()") << QByteArray("")
767 << QStringLiteral(
768 "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288f"
769 "ebcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3");
770 QTest::newRow(dataTag: "whirlpool(a)") << QByteArray("a")
771 << QStringLiteral(
772 "8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413ae"
773 "ff63a42391a39145a591a92200d560195e53b478584fdae231a");
774 QTest::newRow(dataTag: "whirlpool(abc)") << QByteArray("abc")
775 << QStringLiteral(
776 "4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c"
777 "57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5");
778 QTest::newRow(dataTag: "whirlpool(md)") << QByteArray("message digest")
779 << QStringLiteral(
780 "378c84a4126e2dc6e56dcc7458377aac838d00032230f53ce1f5700c0ffb4d3b8421557659ef"
781 "55c106b4b52ac5a4aaa692ed920052838f3362e86dbd37a8903e");
782 QTest::newRow(dataTag: "whirlpool(a-k)") << QByteArray("abcdbcdecdefdefgefghfghighijhijk")
783 << QStringLiteral(
784 "2a987ea40f917061f5d6f0a0e4644f488a7a5a52deee656207c562f988e95c6916bdc8031bc"
785 "5be1b7b947639fe050b56939baaa0adff9ae6745b7b181c3be3fd");
786 QTest::newRow(dataTag: "whirlpool(a-z)") << QByteArray("abcdefghijklmnopqrstuvwxyz")
787 << QStringLiteral(
788 "f1d754662636ffe92c82ebb9212a484a8d38631ead4238f5442ee13b8054e41b08bf2a9251c"
789 "30b6a0b8aae86177ab4a6f68f673e7207865d5d9819a3dba4eb3b");
790 QTest::newRow(dataTag: "whirlpool(A-9)") << QByteArray("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
791 << QStringLiteral(
792 "dc37e008cf9ee69bf11f00ed9aba26901dd7c28cdec066cc6af42e40f82f3a1e08eba266291"
793 "29d8fb7cb57211b9281a65517cc879d7b962142c65f5a7af01467");
794 QTest::newRow(dataTag: "whirlpool(1-0)")
795 << QByteArray("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
796 << QStringLiteral(
797 "466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538cd047b2681a51a2c60481"
798 "e88c5a20b2c2a80cf3a9a083b");
799}
800
801void HashUnitTest::whirlpooltest()
802{
803 bool anyProviderTested = false;
804 QFETCH(QByteArray, input);
805 QFETCH(QString, expectedHash);
806
807 foreach (QString provider, providersToTest) {
808 if (QCA::isSupported(features: "whirlpool", provider)) {
809 anyProviderTested = true;
810
811 QCA::Hash hash = QCA::Hash(QStringLiteral("whirlpool"), provider);
812 QCA::Hash copy = hash;
813 hash.context(); // detach
814
815 QCOMPARE(hash.hashToString(input), expectedHash);
816 QCOMPARE(copy.hashToString(input), expectedHash);
817 }
818 }
819 if (!anyProviderTested)
820 qWarning() << "NONE of the providers supports Whirlpool:" << providersToTest;
821}
822
823void HashUnitTest::whirlpoollongtest()
824{
825 QByteArray fillerString;
826 fillerString.fill(c: 'a', size: 1000);
827
828 foreach (QString provider, providersToTest) {
829 if (QCA::isSupported(features: "whirlpool", provider)) {
830 QCA::Hash rmdHash(QStringLiteral("whirlpool"), provider);
831
832 // This is the "million times 'a' test"
833 for (int i = 0; i < 1000; i++)
834 rmdHash.update(a: fillerString);
835 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
836 QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32"
837 "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01"));
838
839 rmdHash.clear();
840 for (int i = 0; i < 1000; i++)
841 rmdHash.update(a: fillerString);
842 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
843 QStringLiteral("0c99005beb57eff50a7cf005560ddf5d29057fd86b20bfd62deca0f1ccea4af51fc15490eddc47af32"
844 "bb2b66c34ff9ad8c6008ad677f77126953b226e4ed8b01"));
845
846 // This is the "8 rounds of 1234567890" test.
847 // It also ensure that we can re-use hash objects correctly.
848 static char bindata[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30};
849 QByteArray fillerArray(bindata, sizeof(bindata)); // "1234567890"
850 rmdHash.clear();
851 for (int i = 0; i < 8; i++)
852 rmdHash.update(a: fillerArray);
853 QCOMPARE(QString(QCA::arrayToHex(rmdHash.final().toByteArray())),
854 QStringLiteral("466ef18babb0154d25b9d38a6414f5c08784372bccb204d6549c4afadb6014294d5bd8df2a6c44e538"
855 "cd047b2681a51a2c60481e88c5a20b2c2a80cf3a9a083b"));
856 }
857 }
858}
859
860QTEST_MAIN(HashUnitTest)
861
862#include "hashunittest.moc"
863

source code of qca/unittest/hashunittest/hashunittest.cpp