File: serial_hasher_test.cc

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (128 lines) | stat: -rw-r--r-- 3,495 bytes parent folder | download
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();
}