update cmake file

master
coronaPolvo 3 years ago
parent 1fd0c6ebe3
commit 25fba2b5dc

@ -11,5 +11,21 @@ set(fastcoll_SOURCES
main.cpp
main.hpp
md5.cpp)
find_package(Boost REQUIRED COMPONENTS
filesystem
program_options
lexical_cast
timer
cstdint
)
if(NOT Boost_FOUND)
message("Not found Boost")
endif()
include_directories(${Boost_INCLUDE_DIRS})
message("${Boost_INCLUDE_DIRS}")
message("${Boost_LIBRARIES}")
add_executable(fastcoll ${fastcoll_SOURCES})
target_link_libraries(fastcoll boost_system-mt boost_filesystem-mt boost_program_options-mt)
target_link_libraries(fastcoll boost_system-mt boost_filesystem-mt boost_program_options-mt)

@ -5,10 +5,10 @@ CC=gcc
CFLAGS=-g -Wall -O2
.cpp.o:
$(CXX) $(CFLAGS) -c $^ $(INC_DIR)
$(CXX) $(CFLAGS) -c $^ $(INC_DIR) -lboost_filesystem -lboost_system -lboost_thread -lpthread
.cc.o:
$(CC) $(CFLAGS) -c -std=c99 -x c $^ $(INC_DIR)
$(CC) $(CFLAGS) -c -std=c99 -x c $^ $(INC_DIR) -lboost_filesystem -lboost_system -lboost_thread -lpthread
.c.o:
$(CC) $(CFLAGS) -c $^ $(INC_DIR)
@ -22,7 +22,8 @@ all: $(BIN)
$(BIN): $(BIN_OBJS)
$(CXX) $(CFLAGS) -o $@ $^ $(LIB)
fastcoll: main.o md5.o block0.o block1.o block1stevens00.o block1stevens01.o block1stevens10.o block1stevens11.o block1wang.o
fastcoll: main.o md5.o block0.o block1.o block1stevens00.o block1stevens01.o block1stevens10.o block1stevens11.o block1wang.o -lboost_filesystem -lboost_system -lboost_thread -lpthread -lboost_timer -lboost_program_options
clean:
rm -f *.o $(BIN)
rm -f *.o $(BIN)

@ -1,4 +1,65 @@
clone-fastcoll
==============
# FastColl
[TOC]
本仓库源代码来自http://www.win.tue.nl/hashclash/
本仓库主要贡献如下:
1. fastcoll初代代码版本过于久远编译过程会报错
2. 提供适配新版g++和make的配置文件
3. 对fastcoll的功能进行总结与说明
4. 提供fastcoll编译教程
## 如何编译?
### 代码下载与编译
本项目代码已在github中开源。仓库地址为https://github.com/coronaPolvo/fastcoll。用户可以执行如下指令下载全部仓库
```
git clone https://github.com/coronaPolvo/fastcoll.git
```
本项目需要在Linux下进行编译运行。在项目仓库中已提供好Makefile文件用户可以通过以下命令编译运行
```shell
make
```
### boost环境配置
在代码实现中使用了 C++ boost库因此需要配置boost的使用环境。配置步骤如下
1. 在官网下载boost后解压
2. 进入到boost文件夹中以root权限运行./bootstrap.sh
3. 运行./b2 install
当然也可以直接使用系统源进行安装比如ubuntu用户可以用如下命令进行安装
```shell
sudo apt-get update
sudo apt-get install libboost-dev
```
我使用的boost版本是1.77.0
## 功能说明
你可以使用`./fastcoll -h`来查看可选的选项;
```
Allowed options:
-h [ --help ] Show options.
-q [ --quiet ] Be less verbose.
-i [ --ihv ] arg Use specified initial value. Default is MD5 initial
value.
-p [ --prefixfile ] arg Calculate initial value using given prefixfile. Also
copies data to output files.
-o [ --out ] arg Set output filenames. This must be the last option
and exactly 2 filenames must be specified.
Default: -o msg1.bin msg2.bin
```
clone fastcoll_v1.0.0.5_source.zip from http://www.win.tue.nl/hashclash/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1 @@
a.txt

@ -22,7 +22,7 @@ version 1.0.0.5, April 2006.
Copyright
=========
© M. Stevens, 2006. All rights reserved.
<EFBFBD> M. Stevens, 2006. All rights reserved.
Disclaimer
==========
@ -58,17 +58,20 @@ unsigned load_block(istream& i, uint32 block[]);
void save_block(ostream& o, const uint32 block[]);
void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[], uint32 msg2block0[], uint32 msg2block1[], bool verbose = false);
#if 1
// 通过修改1变成0可以更改版本
#if 0
// example trivial version with md5 initial value
// 使用md5进行碰撞的普通版本
int main(int argc, char *argv[])
{
if (argc != 2)
{
// 提示用户按照正确的方式使用代码
printf("Usage: %s <file_name>\n", argv[0]);
return 0;
}
// 定义32位的随机种子
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
@ -110,6 +113,7 @@ int main(int argc, char *argv[])
#include <sstream>
#include <string>
#include <utility>
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>
#include <boost/lexical_cast.hpp>
@ -129,11 +133,12 @@ void test_all();
int main(int argc, char** argv)
{
// 定义随机种子
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
// 指定输出路径
string outfn1 = "msg1.bin";
string outfn2 = "msg2.bin";
string ihv;
@ -141,8 +146,8 @@ int main(int argc, char** argv)
bool verbose = true;
cout <<
"MD5 collision generator v1.5\n"
"by Marc Stevens (http://www.win.tue.nl/hashclash/)\n"
"MD5 collision generator\n"
"应用密码学大作业-任意文件MD5碰撞\n"
<< endl;
try
@ -199,8 +204,10 @@ int main(int argc, char** argv)
outfn1 = prefixfn.substr(0, l-4) + "_msg1" + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2" + prefixfn.substr(l-4);
unsigned i = 1;
while ( fs::exists(fs::path(outfn1, fs::native))
|| fs::exists(fs::path(outfn2, fs::native)))
fs::path path1(outfn1);
fs::path path2(outfn2);
while ( fs::exists(path1)
|| fs::exists(path2))
{
outfn1 = prefixfn.substr(0, l-4) + "_msg1_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
@ -462,3 +469,4 @@ void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[],
if (verbose)
cout << endl;
}

BIN
main.o

Binary file not shown.

BIN
md5.o

Binary file not shown.

@ -0,0 +1,465 @@
/*
MD5 collision generator
=======================
Source code files:
block0.cpp
block1.cpp
main.cpp
main.hpp
md5.cpp
block1wang.cpp
block1stevens00.cpp
block1stevens01.cpp
block1stevens10.cpp
block1stevens11.cpp
Win32 executable:
fastcoll_v1.0.0.5.exe
Version
=======
version 1.0.0.5, April 2006.
Copyright
=========
© M. Stevens, 2006. All rights reserved.
Disclaimer
==========
This software is provided as is. Use is at the user's risk.
No guarantee whatsoever is given on how it may function or malfunction.
Support cannot be expected.
This software is meant for scientific and educational purposes only.
It is forbidden to use it for other than scientific or educational purposes.
In particular, commercial and malicious use is not allowed.
Further distribution of this software, by whatever means, is not allowed
without our consent.
This includes publication of source code or executables in printed form,
on websites, newsgroups, CD-ROM's, etc.
Changing the (source) code without our consent is not allowed.
In all versions of the source code this disclaimer, the copyright
notice and the version number should be present.
*/
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdio.h>
#include "main.hpp"
using namespace std;
// IV = 0123456789abcdeffedcba9876543210
const uint32 MD5IV[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
unsigned load_block(istream& i, uint32 block[]);
void save_block(ostream& o, const uint32 block[]);
void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[], uint32 msg2block0[], uint32 msg2block1[], bool verbose = false);
#if 1
// example trivial version with md5 initial value
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <file_name>\n", argv[0]);
return 0;
}
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
ifstream ifs(argv[1], ios::binary);
ofstream ofs1("md5_data1", ios::binary);
ofstream ofs2("md5_data2", ios::binary);
uint32 block[16];
while (true)
{
unsigned len = load_block(ifs, block);
if (len)
{
save_block(ofs1, block);
save_block(ofs2, block);
md5_compress(IV, block);
} else
break;
}
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1, true);
save_block(ofs1, msg1block0);
save_block(ofs1, msg1block1);
save_block(ofs2, msg2block0);
save_block(ofs2, msg2block1);
printf("use 'md5sum md5_data*' check MD5\n");
return 0;
}
#else
#include <sstream>
#include <string>
#include <utility>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/timer.hpp>
#include <boost/cstdint.hpp>
typedef boost::uint64_t uint64;
namespace fs = boost::filesystem;
namespace po = boost::program_options;
using boost::lexical_cast;
void test_md5iv(bool single = false);
void test_rndiv(bool single = false);
void test_reciv(bool single = false);
void test_all();
int main(int argc, char** argv)
{
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
string outfn1 = "msg1.bin";
string outfn2 = "msg2.bin";
string ihv;
string prefixfn;
bool verbose = true;
cout <<
"MD5 collision generator v1.5\n"
"by Marc Stevens (http://www.win.tue.nl/hashclash/)\n"
<< endl;
try
{
boost::timer runtime;
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "Show options.")
("quiet,q", "Be less verbose.")
("ihv,i", po::value<string>(&ihv), "Use specified initial value. Default is MD5 initial value.")
("prefixfile,p", po::value<string>(&prefixfn), "Calculate initial value using given prefixfile. Also copies data to output files.")
("out,o", po::value<vector<string> >()->multitoken(), "Set output filenames. This must be the last option and exactly 2 filenames must be specified. \nDefault: -o msg1.bin msg2.bin")
;
po::options_description hidden;
hidden.add_options()
("testmd5iv", "Endlessly time collision generation using MD5 initial value.")
("testrndiv", "Endlessly time collision generation using arbitrary random initial values.")
("testreciv", "Endlessly time collision generation using recommended random initial values.")
("testall", "Endlessly time collision generation for each case.")
;
po::options_description cmdline;
cmdline.add(desc).add(hidden);
po::positional_options_description p;
p.add("prefixfile", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(cmdline).positional(p).run(), vm);
po::notify(vm);
if (vm.count("quiet"))
verbose = false;
if (vm.count("help") || argc == 1) {
cout << desc << endl;
return 1;
}
if (vm.count("testmd5iv"))
test_md5iv();
if (vm.count("testrndiv"))
test_rndiv();
if (vm.count("testreciv"))
test_reciv();
if (vm.count("testall"))
test_all();
if (vm.count("prefixfile"))
{
unsigned l = prefixfn.size();
if (l >= 4 && prefixfn[l-4]=='.' && prefixfn[l-3]!='.' && prefixfn[l-2]!='.' && prefixfn[l-1]!='.')
{
outfn1 = prefixfn.substr(0, l-4) + "_msg1" + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2" + prefixfn.substr(l-4);
unsigned i = 1;
while ( fs::exists(fs::path(outfn1, fs::native))
|| fs::exists(fs::path(outfn2, fs::native)))
{
outfn1 = prefixfn.substr(0, l-4) + "_msg1_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
++i;
}
}
}
if (vm.count("out"))
{
vector<string> outfns = vm["out"].as< vector<string> >();
if (outfns.size() != 2)
{
cerr << "Error: exactly two output filenames should be specified." << endl;
return 1;
}
outfn1 = outfns[0];
outfn2 = outfns[1];
}
if (verbose)
cout << "Using output filenames: '" << outfn1 << "' and '" << outfn2 << "'" << endl;
ofstream ofs1(outfn1.c_str(), ios::binary);
if (!ofs1)
{
cerr << "Error: cannot open outfile: '" << outfn1 << "'" << endl;
return 1;
}
ofstream ofs2(outfn2.c_str(), ios::binary);
if (!ofs2)
{
cerr << "Error: cannot open outfile: '" << outfn2 << "'" << endl;
return 1;
}
if (vm.count("prefixfile"))
{
if (verbose)
cout << "Using prefixfile: '" << prefixfn << "'" << endl;
ifstream ifs(prefixfn.c_str(), ios::binary);
if (!ifs)
{
cerr << "Error: cannot open inputfile: '" << prefixfn << "'" << endl;
return 1;
}
uint32 block[16];
while (true)
{
unsigned len = load_block(ifs, block);
if (len)
{
save_block(ofs1, block);
save_block(ofs2, block);
md5_compress(IV, block);
} else
break;
}
}
else
{
if (vm.count("ihv") == 0)
ihv = "0123456789abcdeffedcba9876543210";
if (ihv.size() != 32)
{
cerr << "Error: an initial value must be specified as a hash value of 32 hexadecimal characters." << endl;
return 1;
} else
{
uint32 c;
for (unsigned i = 0; i < 4; ++i)
{
IV[i] = 0;
for (unsigned b = 0; b < 4; ++b)
{
stringstream ss;
ss << ihv.substr(i*8+b*2,2);
ss >> hex >> c;
IV[i] += c << (b*8);
}
}
}
}
if (verbose)
{
cout << "Using initial value: " << hex;
unsigned oldwidth = cout.width(2);
char oldfill = cout.fill('0');
for (unsigned i = 0; i < 4; ++i)
{
for (unsigned b = 0; b < 4; ++b)
{
cout.width(2);
cout.fill('0');
cout << ((IV[i]>>(b*8))&0xFF);
}
}
cout.width(oldwidth);
cout.fill(oldfill);
cout << dec << endl;
}
if (verbose)
cout << endl;
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1, true);
save_block(ofs1, msg1block0);
save_block(ofs1, msg1block1);
save_block(ofs2, msg2block0);
save_block(ofs2, msg2block1);
if (verbose)
cout << "Running time: " << runtime.elapsed() << " s" << endl;
return 0;
} catch (exception& e)
{
cerr << "\nException caught:\n" << e.what() << endl;
return 1;
} catch (...)
{
cerr << "\nUnknown exception caught!" << endl;
return 1;
}
}
void test_md5iv(bool single)
{
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_md5iv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_rndiv(bool single)
{
uint32 IV[4];
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
IV[0] = xrng64(); IV[1] = xrng64(); IV[2] = xrng64(); IV[3] = xrng64();
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_rndiv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_reciv(bool single)
{
uint32 IV[4];
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
IV[0] = xrng64(); IV[1] = xrng64(); IV[2] = xrng64(); IV[3] = xrng64();
IV[2] |= 1<<25; IV[2] ^= ((IV[2] & (1<<24))<<1);
IV[3] &= ~(1<<25); IV[3] ^= ((IV[3] & (1<<24))<<1);
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_reciv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_all()
{
while (true)
{
test_md5iv(true);
test_reciv(true);
test_rndiv(true);
}
}
#endif
unsigned load_block(istream& i, uint32 block[])
{
unsigned len = 0;
char uc;
for (unsigned k = 0; k < 16; ++k)
{
block[k] = 0;
for (unsigned c = 0; c < 4; ++c)
{
i.get(uc);
if (i)
++len;
else
uc = 0;
block[k] += uint32((unsigned char)(uc))<<(c*8);
}
}
return len;
}
void save_block(ostream& o, const uint32 block[])
{
for (unsigned k = 0; k < 16; ++k)
for (unsigned c = 0; c < 4; ++c)
o << (unsigned char)((block[k] >> (c*8))&0xFF);
}
void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[], uint32 msg2block0[], uint32 msg2block1[], bool verbose)
{
if (verbose)
cout << "Generating first block: " << flush;
find_block0(msg1block0, IV);
uint32 IHV[4] = { IV[0], IV[1], IV[2], IV[3] };
md5_compress(IHV, msg1block0);
if (verbose)
cout << endl << "Generating second block: " << flush;
find_block1(msg1block1, IHV);
for (int t = 0; t < 16; ++t)
{
msg2block0[t] = msg1block0[t];
msg2block1[t] = msg1block1[t];
}
msg2block0[4] += 1 << 31; msg2block0[11] += 1 << 15; msg2block0[14] += 1 << 31;
msg2block1[4] += 1 << 31; msg2block1[11] -= 1 << 15; msg2block1[14] += 1 << 31;
if (verbose)
cout << endl;
}
6ò7Í°Š&@ˆ°é¥ë1€<31>äì_„3†AO¸¶øì£ýÄÞÎK&ݵkÖ½!4NWi¾?`Š„Adõ[DíjHÇ~†°§±ÐdlÓd{ž¡mFëû~<15>[[ ÏÁ5ÎÈôHs÷'šky%q^©DìÙ5 R*a31ßn0

@ -0,0 +1,465 @@
/*
MD5 collision generator
=======================
Source code files:
block0.cpp
block1.cpp
main.cpp
main.hpp
md5.cpp
block1wang.cpp
block1stevens00.cpp
block1stevens01.cpp
block1stevens10.cpp
block1stevens11.cpp
Win32 executable:
fastcoll_v1.0.0.5.exe
Version
=======
version 1.0.0.5, April 2006.
Copyright
=========
© M. Stevens, 2006. All rights reserved.
Disclaimer
==========
This software is provided as is. Use is at the user's risk.
No guarantee whatsoever is given on how it may function or malfunction.
Support cannot be expected.
This software is meant for scientific and educational purposes only.
It is forbidden to use it for other than scientific or educational purposes.
In particular, commercial and malicious use is not allowed.
Further distribution of this software, by whatever means, is not allowed
without our consent.
This includes publication of source code or executables in printed form,
on websites, newsgroups, CD-ROM's, etc.
Changing the (source) code without our consent is not allowed.
In all versions of the source code this disclaimer, the copyright
notice and the version number should be present.
*/
#include <iostream>
#include <fstream>
#include <time.h>
#include <stdio.h>
#include "main.hpp"
using namespace std;
// IV = 0123456789abcdeffedcba9876543210
const uint32 MD5IV[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 };
unsigned load_block(istream& i, uint32 block[]);
void save_block(ostream& o, const uint32 block[]);
void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[], uint32 msg2block0[], uint32 msg2block1[], bool verbose = false);
#if 1
// example trivial version with md5 initial value
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <file_name>\n", argv[0]);
return 0;
}
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
ifstream ifs(argv[1], ios::binary);
ofstream ofs1("md5_data1", ios::binary);
ofstream ofs2("md5_data2", ios::binary);
uint32 block[16];
while (true)
{
unsigned len = load_block(ifs, block);
if (len)
{
save_block(ofs1, block);
save_block(ofs2, block);
md5_compress(IV, block);
} else
break;
}
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1, true);
save_block(ofs1, msg1block0);
save_block(ofs1, msg1block1);
save_block(ofs2, msg2block0);
save_block(ofs2, msg2block1);
printf("use 'md5sum md5_data*' check MD5\n");
return 0;
}
#else
#include <sstream>
#include <string>
#include <utility>
#include <boost/filesystem/operations.hpp>
#include <boost/program_options.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/timer.hpp>
#include <boost/cstdint.hpp>
typedef boost::uint64_t uint64;
namespace fs = boost::filesystem;
namespace po = boost::program_options;
using boost::lexical_cast;
void test_md5iv(bool single = false);
void test_rndiv(bool single = false);
void test_reciv(bool single = false);
void test_all();
int main(int argc, char** argv)
{
seed32_1 = uint32(time(NULL));
seed32_2 = 0x12345678;
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
string outfn1 = "msg1.bin";
string outfn2 = "msg2.bin";
string ihv;
string prefixfn;
bool verbose = true;
cout <<
"MD5 collision generator v1.5\n"
"by Marc Stevens (http://www.win.tue.nl/hashclash/)\n"
<< endl;
try
{
boost::timer runtime;
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "Show options.")
("quiet,q", "Be less verbose.")
("ihv,i", po::value<string>(&ihv), "Use specified initial value. Default is MD5 initial value.")
("prefixfile,p", po::value<string>(&prefixfn), "Calculate initial value using given prefixfile. Also copies data to output files.")
("out,o", po::value<vector<string> >()->multitoken(), "Set output filenames. This must be the last option and exactly 2 filenames must be specified. \nDefault: -o msg1.bin msg2.bin")
;
po::options_description hidden;
hidden.add_options()
("testmd5iv", "Endlessly time collision generation using MD5 initial value.")
("testrndiv", "Endlessly time collision generation using arbitrary random initial values.")
("testreciv", "Endlessly time collision generation using recommended random initial values.")
("testall", "Endlessly time collision generation for each case.")
;
po::options_description cmdline;
cmdline.add(desc).add(hidden);
po::positional_options_description p;
p.add("prefixfile", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(cmdline).positional(p).run(), vm);
po::notify(vm);
if (vm.count("quiet"))
verbose = false;
if (vm.count("help") || argc == 1) {
cout << desc << endl;
return 1;
}
if (vm.count("testmd5iv"))
test_md5iv();
if (vm.count("testrndiv"))
test_rndiv();
if (vm.count("testreciv"))
test_reciv();
if (vm.count("testall"))
test_all();
if (vm.count("prefixfile"))
{
unsigned l = prefixfn.size();
if (l >= 4 && prefixfn[l-4]=='.' && prefixfn[l-3]!='.' && prefixfn[l-2]!='.' && prefixfn[l-1]!='.')
{
outfn1 = prefixfn.substr(0, l-4) + "_msg1" + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2" + prefixfn.substr(l-4);
unsigned i = 1;
while ( fs::exists(fs::path(outfn1, fs::native))
|| fs::exists(fs::path(outfn2, fs::native)))
{
outfn1 = prefixfn.substr(0, l-4) + "_msg1_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
outfn2 = prefixfn.substr(0, l-4) + "_msg2_" + lexical_cast<string>(i) + prefixfn.substr(l-4);
++i;
}
}
}
if (vm.count("out"))
{
vector<string> outfns = vm["out"].as< vector<string> >();
if (outfns.size() != 2)
{
cerr << "Error: exactly two output filenames should be specified." << endl;
return 1;
}
outfn1 = outfns[0];
outfn2 = outfns[1];
}
if (verbose)
cout << "Using output filenames: '" << outfn1 << "' and '" << outfn2 << "'" << endl;
ofstream ofs1(outfn1.c_str(), ios::binary);
if (!ofs1)
{
cerr << "Error: cannot open outfile: '" << outfn1 << "'" << endl;
return 1;
}
ofstream ofs2(outfn2.c_str(), ios::binary);
if (!ofs2)
{
cerr << "Error: cannot open outfile: '" << outfn2 << "'" << endl;
return 1;
}
if (vm.count("prefixfile"))
{
if (verbose)
cout << "Using prefixfile: '" << prefixfn << "'" << endl;
ifstream ifs(prefixfn.c_str(), ios::binary);
if (!ifs)
{
cerr << "Error: cannot open inputfile: '" << prefixfn << "'" << endl;
return 1;
}
uint32 block[16];
while (true)
{
unsigned len = load_block(ifs, block);
if (len)
{
save_block(ofs1, block);
save_block(ofs2, block);
md5_compress(IV, block);
} else
break;
}
}
else
{
if (vm.count("ihv") == 0)
ihv = "0123456789abcdeffedcba9876543210";
if (ihv.size() != 32)
{
cerr << "Error: an initial value must be specified as a hash value of 32 hexadecimal characters." << endl;
return 1;
} else
{
uint32 c;
for (unsigned i = 0; i < 4; ++i)
{
IV[i] = 0;
for (unsigned b = 0; b < 4; ++b)
{
stringstream ss;
ss << ihv.substr(i*8+b*2,2);
ss >> hex >> c;
IV[i] += c << (b*8);
}
}
}
}
if (verbose)
{
cout << "Using initial value: " << hex;
unsigned oldwidth = cout.width(2);
char oldfill = cout.fill('0');
for (unsigned i = 0; i < 4; ++i)
{
for (unsigned b = 0; b < 4; ++b)
{
cout.width(2);
cout.fill('0');
cout << ((IV[i]>>(b*8))&0xFF);
}
}
cout.width(oldwidth);
cout.fill(oldfill);
cout << dec << endl;
}
if (verbose)
cout << endl;
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1, true);
save_block(ofs1, msg1block0);
save_block(ofs1, msg1block1);
save_block(ofs2, msg2block0);
save_block(ofs2, msg2block1);
if (verbose)
cout << "Running time: " << runtime.elapsed() << " s" << endl;
return 0;
} catch (exception& e)
{
cerr << "\nException caught:\n" << e.what() << endl;
return 1;
} catch (...)
{
cerr << "\nUnknown exception caught!" << endl;
return 1;
}
}
void test_md5iv(bool single)
{
uint32 IV[4] = { MD5IV[0], MD5IV[1], MD5IV[2], MD5IV[3] };
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_md5iv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_rndiv(bool single)
{
uint32 IV[4];
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
IV[0] = xrng64(); IV[1] = xrng64(); IV[2] = xrng64(); IV[3] = xrng64();
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_rndiv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_reciv(bool single)
{
uint32 IV[4];
uint32 msg1block0[16];
uint32 msg1block1[16];
uint32 msg2block0[16];
uint32 msg2block1[16];
boost::timer runtime;
while (true)
{
runtime.restart();
IV[0] = xrng64(); IV[1] = xrng64(); IV[2] = xrng64(); IV[3] = xrng64();
IV[2] |= 1<<25; IV[2] ^= ((IV[2] & (1<<24))<<1);
IV[3] &= ~(1<<25); IV[3] ^= ((IV[3] & (1<<24))<<1);
find_collision(IV, msg1block0, msg1block1, msg2block0, msg2block1);
double time = runtime.elapsed();
cout << endl << "Running time: " << time << " s" << endl;
ofstream of_timings("timings_reciv.txt", ios::app);
of_timings << time << endl;
if (single) return;
}
}
void test_all()
{
while (true)
{
test_md5iv(true);
test_reciv(true);
test_rndiv(true);
}
}
#endif
unsigned load_block(istream& i, uint32 block[])
{
unsigned len = 0;
char uc;
for (unsigned k = 0; k < 16; ++k)
{
block[k] = 0;
for (unsigned c = 0; c < 4; ++c)
{
i.get(uc);
if (i)
++len;
else
uc = 0;
block[k] += uint32((unsigned char)(uc))<<(c*8);
}
}
return len;
}
void save_block(ostream& o, const uint32 block[])
{
for (unsigned k = 0; k < 16; ++k)
for (unsigned c = 0; c < 4; ++c)
o << (unsigned char)((block[k] >> (c*8))&0xFF);
}
void find_collision(const uint32 IV[], uint32 msg1block0[], uint32 msg1block1[], uint32 msg2block0[], uint32 msg2block1[], bool verbose)
{
if (verbose)
cout << "Generating first block: " << flush;
find_block0(msg1block0, IV);
uint32 IHV[4] = { IV[0], IV[1], IV[2], IV[3] };
md5_compress(IHV, msg1block0);
if (verbose)
cout << endl << "Generating second block: " << flush;
find_block1(msg1block1, IHV);
for (int t = 0; t < 16; ++t)
{
msg2block0[t] = msg1block0[t];
msg2block1[t] = msg1block1[t];
}
msg2block0[4] += 1 << 31; msg2block0[11] += 1 << 15; msg2block0[14] += 1 << 31;
msg2block1[4] += 1 << 31; msg2block1[11] -= 1 << 15; msg2block1[14] += 1 << 31;
if (verbose)
cout << endl;
}
6ò7Í°Š&@ˆ°é¥ë1€<31>_„3†AO¸¶øì£ýÄÞÎK&ݵëÖ½!4NWi¾?`Š„Ádõ[DíjHÇ~†°§±ÐdlÓd{ž¡íFëû~<15>[[ ÏÁ5ÎÈôHs÷'šky%ñ]©DìÙ5 R*a3±ßn0

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save