1*e7b1675dSTing-Kang Chang // Copyright 2017 Google Inc.
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang #include "tink/subtle/random.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <set>
20*e7b1675dSTing-Kang Chang #include <string>
21*e7b1675dSTing-Kang Chang #include <vector>
22*e7b1675dSTing-Kang Chang
23*e7b1675dSTing-Kang Chang #include "gmock/gmock.h"
24*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
25*e7b1675dSTing-Kang Chang #include "absl/container/flat_hash_set.h"
26*e7b1675dSTing-Kang Chang #include "absl/types/span.h"
27*e7b1675dSTing-Kang Chang #include "tink/util/secret_data.h"
28*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
29*e7b1675dSTing-Kang Chang
30*e7b1675dSTing-Kang Chang namespace crypto {
31*e7b1675dSTing-Kang Chang namespace tink {
32*e7b1675dSTing-Kang Chang namespace subtle {
33*e7b1675dSTing-Kang Chang namespace {
34*e7b1675dSTing-Kang Chang
35*e7b1675dSTing-Kang Chang // Iterations for statistic tests.
36*e7b1675dSTing-Kang Chang constexpr int kTests = 10000;
37*e7b1675dSTing-Kang Chang
38*e7b1675dSTing-Kang Chang using ::testing::Gt;
39*e7b1675dSTing-Kang Chang using ::testing::Lt;
40*e7b1675dSTing-Kang Chang using ::testing::SizeIs;
41*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
42*e7b1675dSTing-Kang Chang
TEST(RandomTest,MultipleFilledBuffersAreUnique)43*e7b1675dSTing-Kang Chang TEST(RandomTest, MultipleFilledBuffersAreUnique) {
44*e7b1675dSTing-Kang Chang constexpr int kNumRandomItems = 32;
45*e7b1675dSTing-Kang Chang absl::flat_hash_set<std::string> random_strings;
46*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumRandomItems; i++) {
47*e7b1675dSTing-Kang Chang std::string s(16, '\0');
48*e7b1675dSTing-Kang Chang EXPECT_THAT(Random::GetRandomBytes(absl::MakeSpan(s)), IsOk());
49*e7b1675dSTing-Kang Chang random_strings.insert(s);
50*e7b1675dSTing-Kang Chang }
51*e7b1675dSTing-Kang Chang EXPECT_THAT(random_strings, SizeIs(kNumRandomItems));
52*e7b1675dSTing-Kang Chang }
53*e7b1675dSTing-Kang Chang
TEST(RandomTest,MultipleGeneratedRandomStringAreUnique)54*e7b1675dSTing-Kang Chang TEST(RandomTest, MultipleGeneratedRandomStringAreUnique) {
55*e7b1675dSTing-Kang Chang constexpr int kNumRandomItems = 32;
56*e7b1675dSTing-Kang Chang absl::flat_hash_set<std::string> random_strings;
57*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumRandomItems; i++) {
58*e7b1675dSTing-Kang Chang std::string s = Random::GetRandomBytes(16);
59*e7b1675dSTing-Kang Chang EXPECT_THAT(s, SizeIs(16));
60*e7b1675dSTing-Kang Chang random_strings.insert(s);
61*e7b1675dSTing-Kang Chang }
62*e7b1675dSTing-Kang Chang EXPECT_THAT(random_strings, SizeIs(kNumRandomItems));
63*e7b1675dSTing-Kang Chang }
64*e7b1675dSTing-Kang Chang
65*e7b1675dSTing-Kang Chang
TEST(RandomTest,MultipleGeneratedSecretDataAreUnique)66*e7b1675dSTing-Kang Chang TEST(RandomTest, MultipleGeneratedSecretDataAreUnique) {
67*e7b1675dSTing-Kang Chang constexpr int kNumRandomItems = 32;
68*e7b1675dSTing-Kang Chang absl::flat_hash_set<util::SecretData> random_keys;
69*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumRandomItems; i++) {
70*e7b1675dSTing-Kang Chang util::SecretData key = Random::GetRandomKeyBytes(16);
71*e7b1675dSTing-Kang Chang EXPECT_THAT(key, SizeIs(16));
72*e7b1675dSTing-Kang Chang random_keys.insert(key);
73*e7b1675dSTing-Kang Chang }
74*e7b1675dSTing-Kang Chang EXPECT_THAT(random_keys, SizeIs(kNumRandomItems));
75*e7b1675dSTing-Kang Chang }
76*e7b1675dSTing-Kang Chang
TEST(RandomTest,KeyBytesRandomGenerationIsUniform)77*e7b1675dSTing-Kang Chang TEST(RandomTest, KeyBytesRandomGenerationIsUniform) {
78*e7b1675dSTing-Kang Chang constexpr int kKeyLengthInBytes = 32;
79*e7b1675dSTing-Kang Chang std::vector<int> bit_counts(8 * kKeyLengthInBytes);
80*e7b1675dSTing-Kang Chang for (int i = 0; i < kTests; ++i) {
81*e7b1675dSTing-Kang Chang util::SecretData random = Random::GetRandomKeyBytes(kKeyLengthInBytes);
82*e7b1675dSTing-Kang Chang for (int bit = 0; bit < 8 * kKeyLengthInBytes; ++bit) {
83*e7b1675dSTing-Kang Chang if (random[bit / 8] & (1 << (bit % 8))) {
84*e7b1675dSTing-Kang Chang ++bit_counts[bit];
85*e7b1675dSTing-Kang Chang }
86*e7b1675dSTing-Kang Chang }
87*e7b1675dSTing-Kang Chang }
88*e7b1675dSTing-Kang Chang for (int i = 0; i < 8 * kKeyLengthInBytes; ++i) {
89*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Gt(kTests * 0.4)) << i;
90*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Lt(kTests * 0.6)) << i;
91*e7b1675dSTing-Kang Chang }
92*e7b1675dSTing-Kang Chang }
93*e7b1675dSTing-Kang Chang
TEST(RandomTest,UInt8RandomGenerationIsUniform)94*e7b1675dSTing-Kang Chang TEST(RandomTest, UInt8RandomGenerationIsUniform) {
95*e7b1675dSTing-Kang Chang const int kNumBits = 8;
96*e7b1675dSTing-Kang Chang std::vector<int> bit_counts(kNumBits);
97*e7b1675dSTing-Kang Chang for (int i = 0; i < kTests; ++i) {
98*e7b1675dSTing-Kang Chang uint8_t random = Random::GetRandomUInt8();
99*e7b1675dSTing-Kang Chang for (int bit = 0; bit < kNumBits; ++bit) {
100*e7b1675dSTing-Kang Chang if (random & (1 << bit)) {
101*e7b1675dSTing-Kang Chang ++bit_counts[bit];
102*e7b1675dSTing-Kang Chang }
103*e7b1675dSTing-Kang Chang }
104*e7b1675dSTing-Kang Chang }
105*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumBits; ++i) {
106*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Gt(kTests * 0.4)) << i;
107*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Lt(kTests * 0.6)) << i;
108*e7b1675dSTing-Kang Chang }
109*e7b1675dSTing-Kang Chang }
110*e7b1675dSTing-Kang Chang
TEST(RandomTest,UInt16RandomGenerationIsUniform)111*e7b1675dSTing-Kang Chang TEST(RandomTest, UInt16RandomGenerationIsUniform) {
112*e7b1675dSTing-Kang Chang const int kNumBits = 16;
113*e7b1675dSTing-Kang Chang std::vector<int> bit_counts(kNumBits);
114*e7b1675dSTing-Kang Chang for (int i = 0; i < kTests; ++i) {
115*e7b1675dSTing-Kang Chang uint16_t random = Random::GetRandomUInt16();
116*e7b1675dSTing-Kang Chang for (int bit = 0; bit < kNumBits; ++bit) {
117*e7b1675dSTing-Kang Chang if (random & (1 << bit)) {
118*e7b1675dSTing-Kang Chang ++bit_counts[bit];
119*e7b1675dSTing-Kang Chang }
120*e7b1675dSTing-Kang Chang }
121*e7b1675dSTing-Kang Chang }
122*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumBits; ++i) {
123*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Gt(kTests * 0.4)) << i;
124*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Lt(kTests * 0.6)) << i;
125*e7b1675dSTing-Kang Chang }
126*e7b1675dSTing-Kang Chang }
127*e7b1675dSTing-Kang Chang
TEST(RandomTest,UInt32RandomGenerationIsUniform)128*e7b1675dSTing-Kang Chang TEST(RandomTest, UInt32RandomGenerationIsUniform) {
129*e7b1675dSTing-Kang Chang const int kNumBits = 32;
130*e7b1675dSTing-Kang Chang std::vector<int> bit_counts(kNumBits);
131*e7b1675dSTing-Kang Chang for (int i = 0; i < kTests; ++i) {
132*e7b1675dSTing-Kang Chang uint32_t random = Random::GetRandomUInt32();
133*e7b1675dSTing-Kang Chang for (int bit = 0; bit < kNumBits; ++bit) {
134*e7b1675dSTing-Kang Chang if (random & (1 << bit)) {
135*e7b1675dSTing-Kang Chang ++bit_counts[bit];
136*e7b1675dSTing-Kang Chang }
137*e7b1675dSTing-Kang Chang }
138*e7b1675dSTing-Kang Chang }
139*e7b1675dSTing-Kang Chang for (int i = 0; i < kNumBits; ++i) {
140*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Gt(kTests * 0.4)) << i;
141*e7b1675dSTing-Kang Chang EXPECT_THAT(bit_counts[i], Lt(kTests * 0.6)) << i;
142*e7b1675dSTing-Kang Chang }
143*e7b1675dSTing-Kang Chang }
144*e7b1675dSTing-Kang Chang
145*e7b1675dSTing-Kang Chang } // namespace
146*e7b1675dSTing-Kang Chang } // namespace subtle
147*e7b1675dSTing-Kang Chang } // namespace tink
148*e7b1675dSTing-Kang Chang } // namespace crypto
149