I am trying to implement Floyd's cycle finding algorithm for finding a leading 40-bit hash collision in the SHA-1 algorithm. However, my code will not find a repetition even with 800,000,000 hashes. Can I get some help on this issue?
Here is my code for reference.
REMOVED
Note: I want to understand Floyd's cycle finding algorithm, can someone explain the theory and implementation?
EDIT: Finished Solution Thanks everyone for the help, It now finds collisions in ~3,000,000 hashes!
#include "sha.h"
#include "cryptlib.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <random>
#include <bitset>
#include <time.h>
#pragma comment(lib, "cryptlib.lib")
using namespace std;
CryptoPP::SHA1 SHA;
// takes the reference to a char array and fills it
// with random hex values
void randStr(byte(&src)[5]){
const char *hex_digits = "0123456789abcdef";
srand(time(NULL));
for (int i = 0; i < 5; i++) {
src[i] = hex_digits[(rand() % 16)];
}
}
void hash_40(byte (&src)[5], byte (&hash)[5]){
// Temp hash Storage
byte k[CryptoPP::SHA1::DIGESTSIZE];
// SHA Calculation
SHA.CalculateDigest(k, src, 5);
// Copy to hash destination
for (int i = 0; i < 5; i++){
hash[i] = k[i];
}
}
// compares 2 strings to length len
// faster than C: strncmp with compiler
// optimizations and works as unsigned
bool cmp_hash(byte(&a)[5], byte(&b)[5], int len){
for (int i = 0; i < len; ++i){
if (a[i] != b[i]){
return false;
}
}
return true;
}
int main(){
byte
t[5],
h[5],
xT[5],
xH[5];
randStr(t);
copy(begin(t), end(t), begin(h));
hash_40(t, t);
hash_40(h, h);
hash_40(h, h);
copy(begin(t), end(t), begin(xT));
copy(begin(h), end(h), begin(xH));
unsigned long ctr = 0;
while (true){
hash_40(t, t);
hash_40(h, h);
hash_40(h, h);
ctr += 3;
if (cmp_hash(t, h, 5)){
break;
}
if (ctr % 10000 == 0){
cout << ctr << "\r\n";
}
copy(begin(t), end(t), begin(xT));
copy(begin(h), end(h), begin(xH));
}
cout << "\r\n" << xH << "\r\n" << xT << "\r\nHash to the same leading 40 bits\r\n";
system("pause");
return 0;
}
cmp_hashhash
step is reduced to 40 bits; assuminghash.CalculateDigest
is SHA-1, the function that you iterate is 160-bit, and does not enter a cycle in a reasonable time. Change steps involvinghash.CalculateDigest
to truncate to 40 bit (perhaps just by changing 20 to 5), and see the magic of the birthday bound. $\endgroup$