Skip to content

Commit 7c2cc68

Browse files
fix: use secure random for UUID generation (#602)
Replaced the non-cryptographically secure std::mt19937 with std::random_device for generating UUID v4 and v7. This provides a cryptographically secure random source on modern systems. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: wgtmac <4684607+wgtmac@users.noreply.github.com>
1 parent 743c318 commit 7c2cc68

File tree

1 file changed

+13
-21
lines changed

1 file changed

+13
-21
lines changed

src/iceberg/util/uuid.cc

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,14 @@ Uuid::Uuid(std::array<uint8_t, kLength> data) : data_(std::move(data)) {}
116116

117117
Uuid Uuid::GenerateV4() {
118118
static std::random_device rd;
119-
static std::mt19937 gen(rd());
120-
static std::uniform_int_distribution<uint64_t> distrib(
121-
std::numeric_limits<uint64_t>::min(), std::numeric_limits<uint64_t>::max());
122119
std::array<uint8_t, 16> uuid;
123120

124-
// Generate two random 64-bit integers
125-
uint64_t high_bits = distrib(gen);
126-
uint64_t low_bits = distrib(gen);
127-
128-
// Combine them into a uint128_t
129-
uint128_t random_128_bit_number = (static_cast<uint128_t>(high_bits) << 64) | low_bits;
130-
131-
// Copy the bytes into the uuid array
132-
std::memcpy(uuid.data(), &random_128_bit_number, 16);
121+
// Generate 16 random bytes using std::random_device directly.
122+
// std::random_device::operator() returns a 32-bit unsigned integer.
123+
for (size_t i = 0; i < 16; i += 4) {
124+
uint32_t val = rd();
125+
std::memcpy(uuid.data() + i, &val, 4);
126+
}
133127

134128
// Set magic numbers for a "version 4" (pseudorandom) UUID and variant,
135129
// see https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
@@ -161,17 +155,15 @@ Uuid Uuid::GenerateV7(uint64_t unix_ts_ms) {
161155
uuid[4] = (unix_ts_ms >> 8) & 0xFF;
162156
uuid[5] = unix_ts_ms & 0xFF;
163157

164-
// Generate random bytes for the remaining fields
158+
// Generate random bytes for the remaining fields (10 bytes starting from index 6)
159+
// std::random_device::operator() returns a 32-bit unsigned integer.
165160
static std::random_device rd;
166-
static std::mt19937 gen(rd());
167-
static std::uniform_int_distribution<uint16_t> distrib(
168-
std::numeric_limits<uint16_t>::min(), std::numeric_limits<uint16_t>::max());
169-
170-
// Note: uint8_t is invalid for uniform_int_distribution on Windows
171161
for (size_t i = 6; i < 16; i += 2) {
172-
auto rand = static_cast<uint16_t>(distrib(gen));
173-
uuid[i] = (rand >> 8) & 0xFF;
174-
uuid[i + 1] = rand & 0xFF;
162+
uint32_t val = rd();
163+
uuid[i] = (val >> 8) & 0xFF;
164+
if (i + 1 < 16) {
165+
uuid[i + 1] = val & 0xFF;
166+
}
175167
}
176168

177169
// Set magic numbers for a "version 7" (pseudorandom) UUID and variant,

0 commit comments

Comments
 (0)