1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
#include <gtest/gtest.h>
#include <stddef.h>
#include <string>
#include "merkletree/serial_hasher.h"
#include "util/testing.h"
#include "util/util.h"
namespace {
using std::string;
using std::unique_ptr;
const char kTestString[] = "Hello world!";
const size_t kTestStringLength = 12;
typedef struct {
size_t input_length;
const char* input;
const char* output;
} HashTestVector;
// A couple of SHA-256 test vectors from http://csrc.nist.gov/groups/STM/cavp/
HashTestVector test_sha256[] = {
{0, "",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},
{8, "5738c929c4f4ccb6",
"963bb88f27f512777aab6c8b1a02c70ec0ad651d428f870036e1917120fb48bf"},
{63,
"e2f76e97606a872e317439f1a03fcd92e632e5bd4e7cbc4e97f1afc19a16fde9"
"2d77cbe546416b51640cddb92af996534dfd81edb17c4424cf1ac4d75aceeb",
"18041bd4665083001fba8c5411d2d748e8abbfdcdfd9218cb02b68a78e7d4c23"},
// to indicate the end
{0, NULL, NULL}};
// A slightly shorter notation for constructing binary blobs from test vectors.
#define S(t, n) util::BinaryString(string((t), (2 * n)))
// The reverse
#define H(t) util::HexString(t)
template <class T>
HashTestVector* TestVectors();
template <>
HashTestVector* TestVectors<Sha256Hasher>() {
return test_sha256;
}
template <class T>
class SerialHasherTest : public ::testing::Test {
protected:
SerialHasher* hasher_;
HashTestVector* test_vectors_;
SerialHasherTest() : hasher_(new T()), test_vectors_(TestVectors<T>()) {
}
~SerialHasherTest() {
delete hasher_;
}
};
typedef ::testing::Types<Sha256Hasher> Hashers;
TYPED_TEST_CASE(SerialHasherTest, Hashers);
// Known Answer Tests
TYPED_TEST(SerialHasherTest, TestVectors) {
string input, output, digest;
for (size_t i = 0; this->test_vectors_[i].input != NULL; ++i) {
this->hasher_->Reset();
this->hasher_->Update(
S(this->test_vectors_[i].input, this->test_vectors_[i].input_length));
digest = this->hasher_->Final();
EXPECT_STREQ(H(digest).c_str(), this->test_vectors_[i].output);
}
}
// Test fragmented updates
TYPED_TEST(SerialHasherTest, Update) {
string input(kTestString, kTestStringLength), output, digest;
this->hasher_->Reset();
this->hasher_->Update(input);
digest = this->hasher_->Final();
EXPECT_EQ(digest.size(), this->hasher_->DigestSize());
// The same in two chunks
this->hasher_->Reset();
this->hasher_->Update(input.substr(0, kTestStringLength / 2));
this->hasher_->Update(input.substr(kTestStringLength / 2));
output = this->hasher_->Final();
EXPECT_EQ(H(digest), H(output));
}
TYPED_TEST(SerialHasherTest, Create) {
string input, output, digest;
for (size_t i = 0; this->test_vectors_[i].input != NULL; ++i) {
unique_ptr<SerialHasher> new_hasher(this->hasher_->Create());
new_hasher->Reset();
new_hasher->Update(
S(this->test_vectors_[i].input, this->test_vectors_[i].input_length));
digest = new_hasher->Final();
EXPECT_STREQ(H(digest).c_str(), this->test_vectors_[i].output);
}
}
TEST(Sha256Test, StaticDigest) {
string input, output, digest;
for (size_t i = 0; test_sha256[i].input != NULL; ++i) {
digest = Sha256Hasher::Sha256Digest(
S(test_sha256[i].input, test_sha256[i].input_length));
EXPECT_STREQ(H(digest).c_str(), test_sha256[i].output);
}
}
#undef S
#undef H
} // namespace
int main(int argc, char** argv) {
cert_trans::test::InitTesting(argv[0], &argc, &argv, true);
return RUN_ALL_TESTS();
}
|