Skip to content

Instantly share code, notes, and snippets.

@KayEss
Last active February 21, 2019 10:55
Show Gist options
  • Save KayEss/4cf43ebe039438dd2c7201ccab2b2446 to your computer and use it in GitHub Desktop.
Save KayEss/4cf43ebe039438dd2c7201ccab2b2446 to your computer and use it in GitHub Desktop.
Check for 32 byte collisions in urandom output
/**
# Look for 32 byte collisions from urandom.
Compile with:
```
clang++ urandom.cpp -std=c++17 -O3 -o urandom -Werror
```
*/
#include <algorithm>
#include <array>
#include <cstddef>
#include <iostream>
#include <memory>
#include <sys/random.h>
#include <vector>
using block = std::array<unsigned char, 32>;
using inner = std::array<block, 32>; // Must be power of 2
using store = std::array<std::array<std::array<inner, 256>, 256>, 256>;
block const zero = {};
std::string commas(std::size_t n) {
auto s = std::to_string(n);
for(std::size_t index = s.size(); index > 3; index -= 3) {
s.insert(index - 3, 1u, ',');
}
return s;
}
int main() {
auto fdata = [d = std::make_unique<store>()]
(block const &h) mutable -> bool {
auto &pos = (*d)[h[0]][h[1]][h[2]];
auto offset = (h[3] & (pos.size() -1));
if (pos[offset] == h) {
std::cout << "Collision!" << std::endl;
std::exit(1);
} else if (pos[offset] == zero) {
pos[offset] = h;
return true;
}
return false;
};
std::size_t block_count{}, bytes{}, stored{};
while(true) {
for(std::size_t c = 0u; c < (1u << 10); ++c) {
std::array<block, 1024> block;
getrandom(block.data(), block.size() * sizeof(block), 0u);
for (auto const h : block) {
bool const inserted = fdata(h);
if(inserted) {
++stored;
bytes += 32;
}
++block_count;
}
}
std::cout << "Blocks " << commas(block_count) <<
'/' << commas(stored) <<
" size " << commas(bytes >> 20) << "MB" << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment