ADD file via upload

答辩PPT与电子版论文
pos3ym7vj 2 years ago
parent 357757279a
commit d86fc513e4

290
hack.h

@ -0,0 +1,290 @@
#ifndef DES6_HACK_H
#define DES6_HACK_H
#include <iostream>
#include <random>
#include "const.h"
#include "did_table.h"
#include <ctime>
#include <cassert>
#include <set>
#include <algorithm>
using namespace std;
independent_bits_engine<default_random_engine, 64, ull> random_engine;
static DidTable did;
class DesHackHelper {
private:
ull l_match;
ull r_match;
size_t avail_index_num;
int avail_index[8];
public:
DesHackHelper(int mode) {
if (mode == 1) {
l_match = 0x40080000;
r_match = 0x04000000;
avail_index_num = 5;
avail_index[0] = 2;
avail_index[1] = 5;
avail_index[2] = 6;
avail_index[3] = 7;
avail_index[4] = 8;
}
else {
l_match = 0x00200008;
r_match = 0x00000400;
avail_index_num = 2;
avail_index[0] = 1;
avail_index[1] = 4;
}
}
bool inputCheck(const ull& inA, const ull& inB) {
ull inD = calcIp(inA) ^ calcIp(inB);
ull l = left32(inD);
ull r = right32(inD);
return (l == l_match && r == r_match);
}
bool availCheck(const ull& inA, const ull& inB, const ull& outA, const ull& outB) {
return hack(inA, inB, outA, outB, nullptr);
}
bool hack(const ull& inA,
const ull& inB,
const ull& outA,
const ull& outB,
vector<set<int> >* ret_key = nullptr) {
if (!inputCheck(inA, inB)) return false;
ull outD = calcInvPi(outA ^ outB);
ull r6D = right32(outD);
ull c = calcInvPerm(r6D ^ r_match);
ull eA = calcExt(left32(calcInvPi(outA)));
ull eB = calcExt(left32(calcInvPi(outB)));
ull eD = eA ^ eB;
for (unsigned int i = 0; i < avail_index_num; i++) { // each sbox available
int index = avail_index[i] - 1;
int shift_e = (7 - index) * 6;
int sub_eD = (int)((eD & (63ULL << shift_e)) >> shift_e);
int sub_eA = (int)((eA & (63ULL << shift_e)) >> shift_e);
int shift_c = (7 - index) * 4;
int sub_c = (int)((c & (15ULL << shift_c)) >> shift_c);
vector<int> cdt; // candidate
did.get(index, sub_eD, sub_c, cdt);
if (cdt.empty()) {
return false;
}
if (ret_key != nullptr) {
set<int> t;
t.clear();
for (unsigned int j = 0; j < cdt.size(); j++) {
int key_maybe = cdt[j] ^ sub_eA;
if ((*ret_key)[index].count(key_maybe)) {
t.insert(key_maybe);
}
}
(*ret_key)[index].clear();
for (int j : t) {
(*ret_key)[index].insert(j);
}
}
}
return true;
}
void constructCipherPlaintexts(const ull& key, ull& inA, ull& inB, ull& outA, ull& outB, ull in = 0) {// 给定key构造一组明密文对
while (true) {
if (in == 0)
inA = random_engine();
else {
inA = in; // 使用给定的明文
}
ull diff = (l_match << 32) | r_match;
inB = calcInvIp(calcIp(inA) ^ diff);
pre_l3 = 0;
outA = desEncrypt(inA, key);
outB = desEncrypt(inB, key);
if (pre_l3 == ((r_match << 32) | l_match)) {
if (availCheck(inA, inB, outA, outB)) {
//找到了合适的明密文对
printf("--- new cp ---\n");
print_long_hex(inA);
print_long_hex(inB);
print_long_hex(outA);
print_long_hex(outB);
return;
}
}
}
}
};
class DesHacker {
private:
struct PairCp { // a pair of cipher and plaintext 一组明文和密文
ull inA, inB, outA, outB;
PairCp(const ull& inA, const ull& inB, const ull& outA, const ull& outB) :
inA(inA), inB(inB), outA(outA), outB(outB) {}
};
vector<PairCp> cp_m1; // 满足第一种差分特征的明密文对
vector<PairCp> cp_m2; // 满足第二种差分特征的明密文对
DesHackHelper hackerA;
DesHackHelper hackerB;
vector<set<int> > ret_sub_key; // 输入到每个S盒可能的子密钥。一共有64中可能性
vector<int> enum_binary_position; // 需要枚举的14个二进制位的位置
bool found_key; // 是否找到密钥
ull ret_key; // 存放找到的密钥
ull invPc(ull pc2_out) {
ull pc2_in = calcInvPc2(pc2_out);
ull l = left28(pc2_in);
ull r = right28(pc2_in);
for (int j = 0; j < 10; j++) {
l = (0x0fffffff & (l >> 1)) | ((0x00000001 & l) << 27); // right shift
r = (0x0fffffff & (r >> 1)) | ((0x00000001 & r) << 27);
}
ull pc1_out = (l << 28) | r;
ull pc1_in = calcInvPc1(pc1_out);
return pc1_in;
}
int cur_process = 0; // 当前进度
int max_process = 0;
void binaryEnum(ull num) { // 对其他二进制位进行枚举
cur_process++;
if (cur_process % 100 == 0)
printf("process: %d/%d\n", cur_process, max_process);
if (cur_process > max_process) {
cur_process = max_process;
}
int enum_max = (1 << enum_binary_position.size()) - 1;
// if ((target_key & invPc(0xfff03fffffff)) == num)
for (int i = 0; i < enum_max; i++) {
int bin = i; //枚举的14位二进制数
ull key = num;
for (int j : enum_binary_position) {
if (bin & 1) {
key |= (1ULL << j);
}
bin >>= 1;
}
if (desEncrypt(cp_m1[0].inA, key) == cp_m1[0].outA) {
ret_key = key;
found_key = true;
break;
}
}
}
void combine(int deep, ull num) { //对每个S盒可能的子密钥进行组合使用DFS
if (deep >= 8) {
ull out = invPc(num);
binaryEnum(out);
return;
}
if (deep == 2) {
combine(deep + 1, num);
return;
}
for (int i : ret_sub_key[deep]) {
int shift = (7 - deep) * 6;
ull cur = num | (((ull)i) << shift);
combine(deep + 1, cur);
if (found_key) return;
}
}
public:
// ull target_key;
DesHacker() :hackerA(1), hackerB(2), found_key(false), ret_key(0) {
random_engine.seed((ull)time(nullptr));
ret_sub_key.resize(8);
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 64; j++) {
ret_sub_key[i].insert(j); // 一开始存放所有可能的情况,随着分析过程逐步筛减。
}
}
cp_m1.clear();
cp_m2.clear();
enum_binary_position.clear();
ull enum_mask = calcInvPc1((1ULL << 56) - 1);
ull pc_mask = invPc(0xfff03fffffff) ^ (~enum_mask); // 其中等于0的二进制位是需要最后时枚举的一共14位
ull t = pc_mask;
for (int i = 0; i < 64; i++) {
if (!(t & 1))
enum_binary_position.push_back(i);
t >>= 1;
}
}
bool addCipherPlaintexts(ull in1, ull in2, ull out1, ull out2) {
if (hackerA.inputCheck(in1, in2)) {
cp_m1.push_back(PairCp(in1, in2, out1, out2));
return true;
}
else if (hackerB.inputCheck(in1, in2)) {
cp_m2.push_back(PairCp(in1, in2, out1, out2));
return true;
}
else
return false;
}
bool hack() {
found_key = false;
if (cp_m1.empty() || cp_m2.empty()) {
printf("At least one pair of cipher and plaintexts for each mode...\n");
return false;
}
for (unsigned int i = 0; i < cp_m1.size(); i++) {
if (!hackerA.hack(cp_m1[i].inA, cp_m1[i].inB, cp_m1[i].outA, cp_m1[i].outB, &ret_sub_key))
return false;
}
for (unsigned int i = 0; i < cp_m2.size(); i++) {
if (!hackerB.hack(cp_m2[i].inA, cp_m2[i].inB, cp_m2[i].outA, cp_m2[i].outB, &ret_sub_key))
return false;
}
max_process = 1; // 用于展示计算进度
for (int i = 0; i < 8; i++) {
if (i == 2) continue;
max_process *= ret_sub_key[i].size();
}
combine(0, 0ULL); // 对每个可能的密钥进行枚举
return found_key;
}
ull getKey() {
if (found_key)
return ret_key;
else {
printf("Key not found...\n");
return 0;
}
}
};
void constructCipherPlaintexts(const ull& key, int mode,
ull& inA, ull& inB, ull& outA, ull& outB,
const ull& given_inA = 0) {
DesHackHelper hacker(mode);
hacker.constructCipherPlaintexts(key, inA, inB, outA, outB, given_inA);
}
#endif //DES6_HACK_H
#pragma once
Loading…
Cancel
Save