143 lines
4.0 KiB
C++
143 lines
4.0 KiB
C++
/* Copyright (C) 2010 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "lib/self_test.h"
|
|
|
|
#include "maths/MD5.h"
|
|
|
|
class TestMD5 : public CxxTest::TestSuite
|
|
{
|
|
public:
|
|
std::string decode(u8* digest)
|
|
{
|
|
char digeststr[MD5::DIGESTSIZE*2+1];
|
|
for (size_t i = 0; i < MD5::DIGESTSIZE; ++i)
|
|
sprintf_s(digeststr+2*i, 3, "%02x", (unsigned int)digest[i]);
|
|
return digeststr;
|
|
}
|
|
|
|
void compare(const char* input, const char* expected)
|
|
{
|
|
u8 digest[MD5::DIGESTSIZE];
|
|
|
|
MD5 m;
|
|
m.Update((const u8*)input, strlen(input));
|
|
m.Final(digest);
|
|
|
|
TSM_ASSERT_STR_EQUALS(input, decode(digest), expected);
|
|
}
|
|
|
|
void test_rfc()
|
|
{
|
|
compare("", "d41d8cd98f00b204e9800998ecf8427e");
|
|
compare("a", "0cc175b9c0f1b6a831c399e269772661");
|
|
compare("abc", "900150983cd24fb0d6963f7d28e17f72");
|
|
compare("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
|
|
compare("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
|
|
compare("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
|
"d174ab98d277d9f5a5611c2c9f419d9f");
|
|
compare("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
"57edf4a22be3c955ac49da2e2107b67a");
|
|
}
|
|
|
|
void test_align()
|
|
{
|
|
// Make sure it's not sensitive to alignment
|
|
const char* a0 = "a";
|
|
const char* a1 = "?a";
|
|
const char* a2 = "??a";
|
|
const char* a3 = "???a";
|
|
compare(a0+0, "0cc175b9c0f1b6a831c399e269772661");
|
|
compare(a1+1, "0cc175b9c0f1b6a831c399e269772661");
|
|
compare(a2+2, "0cc175b9c0f1b6a831c399e269772661");
|
|
compare(a3+3, "0cc175b9c0f1b6a831c399e269772661");
|
|
}
|
|
|
|
void test_align_long()
|
|
{
|
|
// Make sure it's not sensitive to alignment
|
|
// when processing long chunks (where it won't memcpy to an intermediate buffer)
|
|
std::string a0 (1000, 'a');
|
|
std::string a1 ("?" + a0);
|
|
std::string a2 ("??" + a0);
|
|
std::string a3 ("???" + a0);
|
|
compare(a0.c_str()+0, "cabe45dcc9ae5b66ba86600cca6b8ba8");
|
|
compare(a1.c_str()+1, "cabe45dcc9ae5b66ba86600cca6b8ba8");
|
|
compare(a2.c_str()+2, "cabe45dcc9ae5b66ba86600cca6b8ba8");
|
|
compare(a3.c_str()+3, "cabe45dcc9ae5b66ba86600cca6b8ba8");
|
|
// Matches output from:
|
|
// perl -e'print "a" x 1000'|openssl md5
|
|
}
|
|
|
|
void test_padding()
|
|
{
|
|
// Edge cases for padding
|
|
compare(std::string(54, 'x').c_str(), "61ea0974c662328da964d977a8253873");
|
|
compare(std::string(55, 'x').c_str(), "04364420e25c512fd958a70738aa8f72");
|
|
compare(std::string(56, 'x').c_str(), "668a72d5ba17f08e62dabcafad6db14b");
|
|
compare(std::string(57, 'x').c_str(), "693037871c4a9d3d8685018905cb530a");
|
|
}
|
|
|
|
void test_chunks()
|
|
{
|
|
u8 digest[MD5::DIGESTSIZE];
|
|
|
|
const u8* in = (const u8*)"12345678901234567890123456789012345678901234567890123456789012345678901234567890";
|
|
size_t len = 80;
|
|
const char* expected = "57edf4a22be3c955ac49da2e2107b67a";
|
|
|
|
// Process in one chunk
|
|
{
|
|
MD5 m;
|
|
m.Update(in, len);
|
|
m.Final(digest);
|
|
TS_ASSERT_STR_EQUALS(decode(digest), expected);
|
|
}
|
|
|
|
// Process one byte at a time
|
|
{
|
|
MD5 m;
|
|
for (size_t i = 0; i < len; ++i)
|
|
m.Update(in+i, 1);
|
|
m.Final(digest);
|
|
TS_ASSERT_STR_EQUALS(decode(digest), expected);
|
|
}
|
|
|
|
// Zero-length updates
|
|
{
|
|
MD5 m;
|
|
m.Update(in+0, 1);
|
|
m.Update(in+1, 0);
|
|
m.Update(in+1, len-1);
|
|
m.Update(in+len, 0);
|
|
m.Final(digest);
|
|
TS_ASSERT_STR_EQUALS(decode(digest), expected);
|
|
}
|
|
|
|
// Split at various points
|
|
for (size_t i = 0; i <= len; ++i)
|
|
{
|
|
MD5 m;
|
|
m.Update(in, i);
|
|
m.Update(in+i, len-i);
|
|
m.Final(digest);
|
|
TS_ASSERT_STR_EQUALS(decode(digest), expected);
|
|
}
|
|
}
|
|
};
|
|
|