xref: /aosp_15_r20/external/tink/cc/subtle/random_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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