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