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