扩展欧几里得–根据应用密码学书
//euclidean .h
#pragma once
#include<iostream>
#include<string>
using namespace std;
class Gcd {
public:
int gcd(int x, int y);
//返回1是没有最大最大公约数
int e_gcd(int x, int y);
int extern_gcd(int x, int y);
public:string Euclidean_a;
public:bool flag = 0;
//有最大公约数就为1;
public:
int gcd_niyuan=0;
int gcd_gongyue=0;
};
//euclidean.cpp
#include<iostream>
#include<string>
#include"Euclidean_Algorithm.h"
using namespace std;
int Gcd::gcd(int x, int y)
{
/*if (x < y) {
int change;
change = x;
x = y;
y = x;
}*/
int r;
r = x %y;
cout << r << endl;
if (r == 0)
{
if (y == 1)Euclidean_a="无最大公约数:";
else { Euclidean_a = "有最大公约数:"; flag = 1; };
return y;
}
if (r != 0)gcd(y, r);
}
int Gcd::e_gcd(int y, int x)
{
//y对x;
int e_x1 = 1, e_x2 = 0, e_x3;
int e_y1 = 0, e_y2 = 1, e_y3;
e_x3 = x; e_y3 = y;
while(1)
{
int t1, t2, t3;
if (e_x3%e_y3 == 1)
{
Euclidean_a = "有逆元:";
gcd_niyuan = e_x2 - e_x3 / e_y3*e_y2;
return gcd_niyuan;
}
if (e_x3%e_y3 == 0)
{
Euclidean_a = "有最大公约数";
flag = 1;
gcd_gongyue = e_y3;
return e_y3;
}
int q;
q = e_x3 / e_y3;
t1 = e_x1 - q*e_y1;
t2 = e_x2 - q*e_y2;
t3 = e_x3 - q*e_y3;
e_x1 = e_y1; e_x2 = e_y2; e_x3 = e_y3;
e_y1 = t1; e_y2 = t2; e_y3 = t3;
}
}
int Gcd::extern_gcd(int x, int y)//简易欧几里得算法
{
int qi, r1 = x, r2 = y, x1 = 0, x2 = 1;
int rt, xt;//temp
if (r1%r2 == 1)
{
Euclidean_a = "有逆元";
return x1 - r1/r2*x2;
}
if (r1%r2 == 0)
{
flag = 1;
Euclidean_a = "有最大公约数";
return r2;
}
while (true)
{
qi = r1 / r2;
rt = r1%r2; xt = x1 - qi*x2;
r1 = r2; x1 = x2;
r2 = rt; x2 = xt;
if (r2 == 1)
{
Euclidean_a = "有逆元";
return x2;
}
if (r1%r2 == 0)
{
flag = 1;
Euclidean_a = "有最大公约数";
return r2;
}
cout << x2<<endl;
}
}
DES:
//des.cpp
#include"des.h"
//①bear 关于S盒的选择
/*密码函数f,接收32位数据和48位子密钥,产生一个32位的输出*/
bitset<32> Des::f(bitset<32>R, bitset<48>k) {
bitset<48> expandR;
// 第一步:扩展置换,32 -> 48
for (int i = 0; i<48; ++i)
expandR[47 - i] = R[32 - E[i]];
// 第二步:异或
expandR = expandR ^ k;
// 第三步:查找S_BOX置换表
bitset<32> output;
int x = 0;
for (int i = 0; i<48; i = i + 6)///bear 48位2进制
{
int row = expandR[47 - i] * 2 + expandR[47 - i - 5];
//bear 获取横坐标,个位,和十位,以二进制来显示出来,导致可以获得类似十进制的数据。横坐标
int col = expandR[47 - i - 1] * 8 + expandR[47 - i - 2] * 4 + expandR[47 - i - 3] * 2
+ expandR[47 - i - 4];// bear 类似横坐标,是获取坐标
int num = S_BOX[i / 6][row][col];// bear 使用s盒获取s盒的数据
bitset<4> binary(num); //bear 把获取的数据赋值给定义的binary
output[31 - x] = binary[3]; //把值赋给输出
output[31 - x - 1] = binary[2];
output[31 - x - 2] = binary[1];
output[31 - x - 3] = binary[0];
x += 4;
}
// 第四步:P-置换,32 -> 32
bitset<32> tmp = output;
for (int i = 0; i<32; ++i)
output[31 - i] = tmp[32 - P[i]];
return output;
}
//②关于移位操作
/**
* 对56位密钥的前后部分进行左移
*/
bitset<28> Des::leftShift(bitset<28> k, int shift) // bear shift是存放的移几位,k是移的那个数字
{
bitset<28> tmp = k;
for (int i = 27; i >= 0; --i)
{
if (i - shift<0)
k[i] = tmp[i - shift + 28];//bear 在移位的个数之后的数据前移shift位,在之后的获取前面的shift位
else
k[i] = tmp[i - shift];
}
return k;
}
//bear ③
/**
* 生成16个48位的子密钥
*/
void Des::generateKeys()
{
bitset<56> realKey;
bitset<28> left;
bitset<28> right;
bitset<48> compressKey;
// 去掉奇偶标记位,将64位密钥变成56位
for (int i = 0; i<56; ++i)
realKey[55 - i] = key[64 - PC_1[i]];
// 生成子密钥,保存在 subKeys[16] 中
for (int round = 0; round<16; ++round)
{
// 前28位与后28位
for (int i = 28; i<56; ++i)
left[i - 28] = realKey[i];
for (int i = 0; i<28; ++i)
right[i] = realKey[i];
// 左移
left = leftShift(left, shiftBits[round]);//每一轮
right = leftShift(right, shiftBits[round]);
// 压缩置换,由56位得到48位子密钥
for (int i = 28; i<56; ++i)
realKey[i] = left[i - 28];
for (int i = 0; i<28; ++i)
realKey[i] = right[i];
for (int i = 0; i<48; ++i)
compressKey[47 - i] = realKey[56 - PC_2[i]];
subKey[round] = compressKey;
}
}
/**
* 工具函数:将char字符数组转为二进制
*/
bitset<64> Des::charToBitset(const char s[8])
{
bitset<64> bits;
for (int i = 0; i<8; ++i)
for (int j = 0; j<8; ++j)
bits[i * 8 + j] = ((s[i] >> j) & 1);
return bits;
}
/**
* DES加密
*/
bitset<64> Des::encrypt(bitset<64>& plain)
{
bitset<64> cipher;
bitset<64> currentBits;
bitset<32> left;
bitset<32> right;
bitset<32> newLeft;
zhuan32(plain, 1);
// 第一步:初始置换IP
for (int i = 0; i<64; ++i)
currentBits[63 - i] = plain[64 - IP[i]];
// 第二步:获取 Li 和 Ri
for (int i = 32; i<64; ++i)
left[i - 32] = currentBits[i];
for (int i = 0; i<32; ++i)
right[i] = currentBits[i];
// 第三步:共16轮迭代
L_cipher.push_back(left); R_cipher.push_back(right);
for (int round = 0; round<16; ++round)
{
newLeft = right;if(round<15) L_cipher.push_back(right);
right = left ^ f(right, subKey[round]);
left = newLeft; if(round<15)R_cipher.push_back(right);
}
// 第四步:合并L16和R16,注意合并为 R16L16
R_cipher.push_back(left);
L_cipher.push_back(right);
for (int i = 0; i<32; ++i)
cipher[i] = left[i];
for (int i = 32; i<64; ++i)
cipher[i] = right[i - 32];
// 第五步:结尾置换IP-1
currentBits = cipher;
for (int i = 0; i<64; ++i)
cipher[63 - i] = currentBits[64 - IP_1[i]];
// 返回密文
return cipher;
}
/**
* DES解密
*/
bitset<64> Des::decrypt(bitset<64>& cipher)
{
bitset<64> plain;
bitset<64> currentBits;
bitset<32> left;
bitset<32> right;
bitset<32> newLeft;
zhuan32(cipher,2);
// 第一步:初始置换IP
for (int i = 0; i<64; ++i)
currentBits[63 - i] = cipher[64 - IP[i]];
// 第二步:获取 Li 和 Ri
for (int i = 32; i<64; ++i)
left[i - 32] = currentBits[i];
for (int i = 0; i<32; ++i)
right[i] = currentBits[i];
// 第三步:共16轮迭代(子密钥逆序应用)
L_plain.push_back(left); R_plain.push_back(right);
for (int round = 0; round<16; ++round)
{
newLeft = right; if (round<15) L_plain.push_back(right);
right = left ^ f(right, subKey[15 - round]);
left = newLeft; if (round<15)R_plain.push_back(right);
}
// 第四步:合并L16和R16,注意合并为 R16L16
R_plain.push_back(left);
L_plain.push_back(right);
for (int i = 0; i<32; ++i)
plain[i] = left[i];
for (int i = 32; i<64; ++i)
plain[i] = right[i - 32];
// 第五步:结尾置换IP-1
currentBits = plain;
for (int i = 0; i<64; ++i)
plain[63 - i] = currentBits[64 - IP_1[i]];
// 返回明文
return plain;
}
void Des::use(const char s1[], const char s2[8])
{
list<bitset<64>>::iterator ListIterator;//list迭代器
//初始化现有的链表,避免重复使用
forList();
char s[8];
strcpy_s(s, s2);//复制s2给s
key = charToBitset(s);
generateKeys();//生成16个子密钥 存放subkey[16]
//存放明文
int k = strlen(s1); //获取有几个8位字符,一个字符8个字节。以8个字符为一组
if (k % 8 == 0)
stringN = k / 8;
else
stringN = k / 8 + 1;
for (int i=0; i < stringN; i++)//have number
{
for (int j = 0; j < 8; j++)
{
s[j] = s1[i * 8 + j];//分组
}
plain.push_back(charToBitset(s));//明文,存放二进制明文在list<bitset<64>>的链表中
}
//加密,存放密文
for(ListIterator=plain.begin();ListIterator!=plain.end();++ListIterator)
{
cipher.push_back(encrypt(*ListIterator));
}
//解密,存放解密的文
for (ListIterator = cipher.begin(); ListIterator != cipher.end(); ++ListIterator)
{
c_plain.push_back(decrypt(*ListIterator));
}
//三个存放明文和存放密文 因为在一个函数表现出来,所以不需要我进行改成加密或者解密。加密和解密都是生成bitset
//如果想达到生成的一个密文的解析,需要把密文转换为bitset<64>的数组,然后对数组进行解密。
//需要一个专门的解密函数,可以提取解密bitset的函数出去,然后进行生成明文,提取出去的话,关于key部分也需要提取出来
bitsetToString();//把最后得到的解密的全部提取出来,放在str_plain中
tocipher();
//show(plainLeft);
}
void Des::forList()
{
Str_plain.clear();
plainLeft.clear();
plainRight.clear();
cipherLeft.clear();
cipherRight.clear();
c_plain.clear();//解密的明文
plain.clear();//链表的密文 64进制
cipher.clear();//链表的明文
L_cipher.clear();//加密左
R_cipher.clear();//加密右
}
string Des::bitsetToString()
{
list<bitset<64>>::iterator ListIterator;
char c[8]; bitset<64> A; bitset<8>a;
for (ListIterator = c_plain.begin();ListIterator != c_plain.end(); ListIterator++)
{
A = *ListIterator;
//show(A);//测试
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
a[j] = A[i * 8 + j];
int i1 = a.to_ullong();
if('a'<i1<'Z')
c[i] = i1;//转字符
else
{
c[i] = '\0';
break;
}
}
string temp;
for (int i = 0; i < 8; i++)
{
if (c[i] != '\0')
temp = temp + c[i];
else
break;
}
Str_plain = Str_plain + temp;//存在变量里面
//cout << Str_plain <<"str"<< endl;
}
return Str_plain;
}
void Des::tocipher()
{
list<bitset<64>>::iterator ListIterator;
bitset<64>a;
for (ListIterator = cipher.begin(); ListIterator != cipher.end(); ++ListIterator)
{
a = *ListIterator;
Str_cipher = Str_cipher + a.to_string();//二进制密文
//cout << "二进制密文"<<a << endl;
}
}
void Des::show(bitset<64> a)
{
cout << "show:" << endl;
bitset<8> b; char c[8];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
b[j] = a[i * 8 + j];
}
int num=1;
num = b.to_ulong();
cout << num;
c[i] = num;
if ('a' < num< 'Z')
cout << c[i] << endl;
else break;
}
//system("pause");
}
void Des::zhuan32(bitset<64> a, int b)
{
bitset<32> R, L;
switch (b)
{
case 1:
for (int i = 0; i < 64; i++)
{
if (i < 32)R[i] = a[i];
else
{
L[i - 32] = a[i];
}
}
plainLeft.push_back(L);
plainRight.push_back(R);
//show(L);//
break;
case 2:
for (int i = 0; i < 64; i++)
{
if (i < 32)R[i] = a[i];
else
{
L[i - 32] = a[i];
}
}
cipherLeft.push_back(L);
cipherRight.push_back(R);
break;
default:
break;
}
}
void Des::show(bitset<48> a)
{
cout << "48位:"<<a << endl;
}
void Des::show(bitset<32> a)
{
cout << "32位:" << a << endl;
}
void Des::show(bitset<28> a)
{
cout << "28位:" << a << endl;
}
void Des::show(list < bitset<32>>a)
{
list<bitset<32>>::iterator i;
for (i = a.begin(); i != a.end(); i++)
{
cout << *i << endl;
}
}
void Des::show(list < bitset<64>>a)
{
list<bitset<64>>::iterator i;
for (i = a.begin(); i != a.end(); i++)
{
cout << *i << endl;
}
}
#pragma once
//des.h
#include<iostream>
#include<bitset>
#include<string>
#include<list>
using namespace std;
class Des
{
public:string title = "DES:";
public:
int stringN;
list<bitset<32>>plainLeft;
list<bitset<32>>plainRight;
void zhuan32(bitset<64> a,int b);
list<bitset<32>>cipherLeft;
list<bitset<32>>cipherRight;
public:
list<bitset<64>> c_plain;//解密的明文
public:
list<bitset<64>> plain;//链表的密文 64进制
list < bitset<64>>cipher;//链表的明文
bitset<64>key;//64位密钥
bitset<48> subKey[16];//存放16轮子密钥
public:
list < bitset<32>>L_plain;//jiemi
list<bitset<32>>R_plain;
list<bitset<32>>L_cipher;//加密左
list<bitset<32>>R_cipher;//加密右
public:string Str_plain; //存放解密的文
string Str_cipher;//二进制密文,全部为字符串显示
private: //置换函数
//初始置换表
int IP[64] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
// 结尾置换表
int IP_1[64] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
// 密钥置换表,将64位密钥变成56位
int PC_1[64] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4 };
// 压缩置换,将56位密钥压缩成48位子密钥
int PC_2[64] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32 };
// 每轮左移的位数
int shiftBits[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
/*------------------下面是密码函数 f 所用表-----------------*/
// 扩展置换表,将 32位 扩展至 48位
int E[48] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1 };
// S盒,每个S盒是4x16的置换表,6位 -> 4位
int S_BOX[8][4][16] = {
{
{ 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7 },
{ 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8 },
{ 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0 },
{ 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 }
},
{
{ 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10 },
{ 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5 },
{ 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15 },
{ 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 }
},
{
{ 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8 },
{ 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1 },
{ 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7 },
{ 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 }
},
{
{ 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15 },
{ 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9 },
{ 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4 },
{ 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 }
},
{
{ 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9 },
{ 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6 },
{ 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14 },
{ 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 }
},
{
{ 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11 },
{ 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8 },
{ 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6 },
{ 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 }
},
{
{ 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1 },
{ 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6 },
{ 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2 },
{ 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 }
},
{
{ 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7 },
{ 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2 },
{ 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8 },
{ 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 }
}
};
// P置换,32位 -> 32位
int P[32] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25 };
private:
bitset<32>f(bitset<32>R, bitset<48>k);//密码函数f,接收32位数据和48位子密钥,产生一个32位的输出
bitset<28> leftShift(bitset<28> k, int shift);//对56位密钥的前后部分进行左移
void generateKeys();//生成16个48位的子密钥
private://转换函数
bitset<64> charToBitset(const char s[8]); // 把字符转换为64位二进制
string bitsetToString();
void tocipher();
private://解密
bitset<64> encrypt(bitset<64>& plain); //进行加密
bitset<64> decrypt(bitset<64>& cipher); //进行解密
public:
/*使用,明文没有做要求,可以多输入,然后输出。
*密钥定了数量,最长8位
*结果在字符串里面
*/
void use(const char s1[], const char s2[8]);///入口
private:
void forList();
private://test 控制台窗口可见
void show(bitset<64>a);//测试,展示链表中某个64为二进制的值 已经转换为了64进制
void show(bitset<48>a);//测试,展示链表中某个48为二进制的值
void show(bitset<32>a);//测试,展示链表中某个32为二进制的值
void show(bitset<28>a);//测试,展示链表中某个28为二进制的值
void show(list < bitset<32>>a);
void show(list<bitset<64>>a);
};
class conver
{
};
sha-1
//sha_1.h
#pragma once
#include<iostream>
#include<bitset>
#include<string>
#include<cmath>
using namespace std;
class sha
{
public:
void sha_1_pad(bitset<64> x);
bitset<64> charToBitset(const char s[8]);
bitset<512> M;
int L;//长度
bitset<64> bitL;
bool c = 0;//判断是字符串
public:
bitset<32> A = 0x67452301;
bitset<32>B = 0xefcdab89;
bitset<32>C = 0x98badcfe;
bitset<32>D = 0x10325476;
bitset<32>E = 0xc3d2e1f0;
public:
bitset<32>k[80];
bitset<32>w[80];
void tow();
void for_k();
unsigned _int64 f1234(int t, bitset<32> B, bitset<32>C, bitset<32>D);
public:
void use(const char s[8]);
void hash();
bitset<32> shift(bitset<32> a);
public:
void showw();
void sABCDE();
//string str_plain;
string str_hash;
string title = "SHA-1:";
//string str_hash16;
//void hash16();
};
#include"sha_1.h"
void sha::sha_1_pad(bitset<64> x)
{
M.reset();
for(int i=0;i<64;i++)
{
M[i] = x[i];
}
int length;
if (c)
{
length = 8 * L;
//M=M << 8 * (8 - L);//字符串
}
else {
length = L;
M=M << L;//数据
}
M=M << 448;//把x放在前64位
bitL = length;
for (int i = 0; i < 64; i++)
{
M[i] = bitL[i];
}
M[511 - length] = 1;
}
bitset<64> sha::charToBitset(const char s[8])
{
bitset<64> bits; c = 1;
/*for (int i = 0; i < 8; i++)
cout << s[i] << " ";
cout << endl;*/
L = strlen(s);//多少位,对于字符串的使用
for (int i = 0; i<8; ++i)
for (int j = 0; j<8; ++j)
bits[i * 8 + j] = ((s[7-i] >> j) & 1);
//cout << "bits:"<<bits << endl;
return bits;
}
void sha::for_k()
{
for (int i = 0; i < 80; i++)
{
if (i / 20 == 0)k[i] = 0x5a827999;
else if (i / 20 == 1)k[i] = 0x6ed9eba1;
else if (i / 20 == 2)k[i] = 0x8f1bbcdc;
else k[i] = 0xca62c1d6;
}
}
void sha::tow()
{
for (int i = 15; i>=0; i--)
{
for (int j = 0; j < 32; j++)
w[i][j] = M[j+32*(15-i)];
}
for (int i = 16; i < 80; i++)
{
w[i] = shift((w[i - 16] ^ w[i - 14] ^ w[i - 8] ^ w[i - 3]));
}
}
void sha::use(const char s[8])
{
sha_1_pad(charToBitset(s));
for_k();
tow();
hash();
//printf("%x %x %x %x %x \n", A, B, C, D, E);
//showw();/
str_hash = A.to_string() + B.to_string() + C.to_string() + D.to_string() + E.to_string();
}
void sha::hash()
{
//sABCDE();
// system("pause");
bitset<32>H[5]; H[0] = A; H[1] = B; H[2] = C; H[3] = D; H[4] = E;
bitset<32>temp;
for (int i = 0; i < 80; i++)
{
unsigned _int64 e, s5a, wt, kt, f1;
bitset<32>tp_a = A;
for (int j = 0; j < 5; j++)
tp_a = shift(tp_a);
e = E.to_ullong();
f1 = f1234(i, B, C, D);
s5a = tp_a.to_ullong();
wt = w[i].to_ullong();
kt = k[i].to_ullong();
unsigned _int64 q = pow(2, 32);
temp = (e + f1 + s5a + wt + kt) % q;
//cout << "tp_a" << tp_a << " e" << e << " f1:" << f1 << " s5a" << s5a << " kt" << kt << " q" << q << " temp" << temp << endl;
//cout << "A" << A << "\nB" << B << "\nC" << C << "\nD" << D << "\nE" << E << endl;
E = D;
D = C;
for (int j = 0; j < 30; j++)
B = shift(B);
C = B;
B = A;
A = temp;
//bitset<64>v1 = 0x40000000;
//bitset<64>v2 = 0x7bf36ae2;
//cout << v1 << endl;
//cout << v2 << endl;
//sABCDE();
//system("pause");
}
unsigned _int64 x1, x2;
x1 = A.to_ullong(), x2 = H[0].to_ullong();
A = x1 + x2;
x1 = B.to_ullong(), x2 = H[1].to_ullong();
B = x1 + x2;
x1 = C.to_ullong(); x2 = H[2].to_ullong();
C = x1 + x2;
x1 = D.to_ullong(); x2 = H[3].to_ullong();
D = x1 + x2;
x1 = E.to_ullong(); x2 = H[4].to_ullong();
E = x1 + x2;
}
unsigned _int64 sha::f1234(int t, bitset<32> B, bitset<32>C, bitset<32>D)
{
unsigned _int64 a; bitset<32>A;
int w = t / 20;
switch (w)
{
case 0:
A = (B&C) | ((~B)&D);
break;
case 1:
A = B^C^D;
break;
case 2:
A = (B&C) | (B&D) | (C&D);
break;
case 3:
A = B^C^D;
break;
default:
break;
}
a = A.to_ullong();
return a;
}
void sha::showw()
{
cout <<"L长度"<< L << endl;
for (int i = 0; i < 80; i++)
cout << w[i] << " ";
cout << endl;
for (int i = 0; i < 80; i++)
cout << k[i] << " ";
}
void sha::sABCDE()
{
printf("%x %x %x %x %x \n", A, B, C, D, E);
}
bitset<32> sha::shift(bitset<32> a)
{
bool b;
b = a[31]; int i;
for ( i = 31; i>0; i--)
{
a[i] = a[i -1];
}
//a[i] = 0;
a[i] = b;
//cout << a << endl;
//system("pause");
return a;
}
//void sha::hash16()
//{
// //str_hash16;
//}
RSA 可利用的是快速取模
//rsa.h
#pragma once
#include<iostream>
#include<bitset>
#include<string>
#include<list>
#include<time.h>
#include<cmath>
#include<random>
using namespace std;
/*打算做到的一个事情,是对64位2进制进行加密,可以对DES的64位二进制进行同样的加密。
*但对于大素数,暂时没有找到一个好的办法,第一版本,使用小数代替,实现算法实现
*若有机会,可以去实现大素数的判断
*先想过使用大素数,但是有点麻烦
*/
class Rsa
{
public:
int n;
int e=3;
private:
int d;
int p;
int q;
public:
/*find prime
*p q e n d
**/
void FindPrime();//大数素数创造,未写--2
/*素数测试
*整除测试
*/
int Prime_test(int x);
/*如果使用大数的witness算法
*概率测试,未写---2
*/
//int WITNESS(int a,int n);
private:
//明文和密文
public:string Str_plain; //存放解密的文--字符串
string Str_cipher;
string title = "RSA:";
list<int> c_plain;//解密的明文
private:
list<int> plain;//链表的明文
list < int>cipher;//链表的密文
public:
int encrypt(int & plain); //进行加密
int decrypt(int & cipher); //进行解密
public:
/*工具函数*/
//bitset<64>charToBitset(const char s[8]);//无论是 什么类型都转换未char型
void inttostring();
int kuai(int a, int n, int m);
void use(const char s1[]);
void show();
};
//rsa.cpp
#include"rsa.h"
#include"Euclidean_Algorithm.h"
int Rsa::Prime_test(int n)
{
int r = 2;
while (r<sqrt(n))
{
if (n%r == 0)
return 0;//不是素数
r++;
}
return n;
}
void Rsa::FindPrime()
{
/*随机生成100-1000的素数
*赋值为p,q e
*/
srand(time(NULL)); p = 2; q = 3; int f = 1;
one:
while (true)
{
p = rand() % 100 + 25;
if (Prime_test(p))break;
}
while (true)
{
q = rand() % 100 + 25;
if (Prime_test(q))break;
}
if (p == q)goto one;
//cout << p << "+q+" << q << endl;
n = p*q;
while ((p - 1)*(q - 1) % e == 0)e = e + 2;
Gcd a;
d = -1;
while (d<0)
{
d = a.e_gcd(e, (p-1)*(q-1));
if (d > 0)break;
e = e + 2;
while (1)
{
if ((p - 1)*(q - 1) % e != 0)break;
e = e + 2;
}
}
int f1 = a.e_gcd(d, (p - 1)*(q - 1));
//cout <<"p"<<p<<"q"<<q<<" " <<d<<"dd" << f1 << "d" <<e<< endl;
}
void Rsa::use(const char s1[])
{
list<int>::iterator ListIterator;
FindPrime();
int k = strlen(s1);
//cout << k << "K" << endl;
for (int i = 0; i < k ; i++)//have number
{
plain.push_back(s1[i]);//明文
}
//加密,存放密文
for (ListIterator = plain.begin(); ListIterator != plain.end(); ++ListIterator)
{
cipher.push_back(encrypt(*ListIterator));
}
//解密,存放解密的文
for (ListIterator = cipher.begin(); ListIterator != cipher.end(); ++ListIterator)
{
c_plain.push_back(decrypt(*ListIterator));
}
//三个存放明文和存放密文 因为在一个函数表现出来,所以不需要我进行改成加密或者解密。加密和解密都是生成bitset
//如果想达到生成的一个密文的解析,需要把密文转换为bitset<64>的数组,然后对数组进行解密。
//需要一个专门的解密函数,可以提取解密bitset的函数出去,然后进行生成明文,提取出去的话,关于key部分也需要提取出来
inttostring();
//show();
}
int Rsa::encrypt(int &plain)//进行加密
{
int cipher=0;
cipher=kuai(plain, e, n);
return cipher;
}
int Rsa::decrypt(int &cipher) //进行解密
{
int plain ;
plain = kuai(cipher, d, n);
return plain;
}
int Rsa::kuai(int a,int m,int n)
{
int c = 1,flag=1; int d1 = 1;
bitset<64> bit_m = m;
int k = 0;
for (int i = 0; i < 64; i++)
{
if (bit_m[63 - i] == 1)
{
k = i;
break;
}
}
k = 63 - k;
for (int i = k; i >= 0; i--)
{
if (flag) { flag = 0; }
else
c = 2 * c;
d1 = (d1*d1) % n;
if (bit_m[i] == 1)
{
c = c + 1;
d1 = (d1*a) % n;
}
}
return d1;
}
void Rsa::inttostring()
{
list<int>::iterator ListIterator;
for (ListIterator = c_plain.begin(); ListIterator != c_plain.end(); ++ListIterator)
{
char c = *ListIterator;
Str_plain = Str_plain + c;
}
//cout << "str_plain:"<<Str_plain << endl;
for (ListIterator = cipher.begin(); ListIterator != cipher.end(); ++ListIterator)
{
char c = *ListIterator;
Str_cipher = Str_cipher + c;
}
}
void Rsa::show()
{
cout << "p\tq\tn\te\td\t(p-1)*(q-1)" << endl;
cout << p << "\t" << q << "\t" << n << "\t" << e << "\t" << d <<"\t"<<(p-1)*(q-1)<< endl;
list<int>::iterator ListIterator;
for (ListIterator = plain.begin(); ListIterator != plain.end(); ++ListIterator)
{
cout << *ListIterator << " ";
}
cout << endl;
for (ListIterator = cipher.begin(); ListIterator != cipher.end(); ++ListIterator)
{
cout << *ListIterator << " ";
}
cout << endl;
for (ListIterator = c_plain.begin(); ListIterator != c_plain.end(); ++ListIterator)
{
cout << *ListIterator << " ";
}
cout << endl;
}
RC4:
#pragma once
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
typedef unsigned long ULONG;
class rc42
{
public:
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len);
void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len);
void use(const char a[]);
public:
string str_plain;
string title = "RC42:";
string str_cipher;
};
#include"rc42.h"
void rc42::rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i<256; i++)
{
s[i] = i;
k[i] = key[i%Len];
}
for (i = 0; i<256; i++)
{
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}
void rc42::rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k<Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
void rc42::use(const char a[])
{
unsigned char s[256] = { 0 }, s2[256] = { 0 }; //S-box
char key[256] = { "just for test" };//定义key
int k = strlen(a);
char pData[512];
for (int i = 0; i < k; i++)
pData[i] = a[i];
//char pData[512] = "这是一个用来加密的数据Data";
ULONG len = strlen(pData);
//printf("pData = %s\n", pData);
//printf("key = %s, length = %d\n\n", key, strlen(key));
rc4_init(s, (unsigned char *)key, strlen(key)); //已经完成了初始化
//printf("完成对S[i]的初始化,如下:\n\n");
//for (int i = 0; i<256; i++)
//{
// printf("%-3d ", s[i]);
//}
//printf("\n\n");
for (int i = 0; i<256; i++)//用s2[i]暂时保留经过初始化的s[i],很重要的!!!
{
s2[i] = s[i];
}
//printf("已经初始化,现在加密:\n\n");
rc4_crypt(s, (unsigned char *)pData, len);//加密
//printf("pData = %s\n\n", pData);
//printf("已经加密,现在解密:\n\n");
rc4_init(s, (unsigned char *)key, strlen(key)); //初始化密钥
rc4_crypt(s2, (unsigned char *)pData, len);//解密
//printf("pData = %s\n\n", pData);
pData[k] = '\0';
cout << pData <<" "<< endl;
str_plain = pData;
}
ECC:
#pragma once
//ecc.h
#include<iostream>
#include<list>
#include<string>
#include<cmath>
#include<bitset>
#include<time.h>
#include<random>
using namespace std;
struct GF
{
bitset<4>x;
int xn;
bitset<4>y;
int yn;
};
struct Data
{
bitset<4>x1, y1,x2,y2;
};
class Ecc
{
public:
//Ecc() {
//}
//~Ecc(){}
public:
/*定义曲线
*对椭圆曲线满足的最基本的条件
*y^2+axy+by=x^3+c^2+dx+e;
*为了简便,使用默认值,并以应用密码学第二版-胡向东P143,6-9作为例题计算
*/
int ellipse_a=1;
int ellipse_b=0;
int ellipse_c=3;
int ellipse_d=0;
int ellipse_e=1;
public:
/*定义多项式
*根据简便和题设置为f(x)=x^4+x+1
*所以为GF(2^4)
*理论上可是有的是GF(2^m);m=160为可靠的
*在这里为4和对应2^4=16;
*/
/*如果不像下,需要重载*,如果要使用到椭圆曲线,就需要重载*
*实现俩个功能,1,g[16]好算,2.实现方程相乘
*/
bitset<4> g[17] = {
1,2,4,8,
3,6,12,11,
5,10,7,14,
15,13,9,1,
0};
int find(bitset<4> num);
public:
list<GF> G;
int n;//阶,为G中的个数
list<bitset<8>>m;//存放bitset的消息
list<bitset<8>>sec;//
list < bitset<8>>c_m;//
string str_plain;
string str_cipher;
public:
bitset<8> charToBitset(const char s); // 把字符转换为64位二进制
string bitsetToString();
GF db(GF A);//倍点规则
GF ad(GF A,GF B);//相加规则 A+B
void calu(GF a);///开始计算
GF calu(GF a, int k);
bitset<8> encrypt(bitset<8> &plain); //进行加密
bitset<8> decrypt(bitset<8>&cipher); //进行解密
public:
void use(const char message[]);
void show(GF a);
void showList(list<bitset<8>> L);
//void creat_ellipse();
string title = "ECC:";
private:
int d;//私钥
GF Q;//公钥
Data cipher1;
Data plain1;
};
#include"ecc.h"
void Ecc::calu(GF a)///开始计算
{
int il = 1;
G.push_back(a);
GF Gnext;
Gnext=db(a);
G.push_back(Gnext);
for (int i = 0; Gnext.xn != a.xn; i++)
{
Gnext = ad(a,Gnext);
G.push_back(Gnext);
}
}
GF Ecc::calu(GF a, int k)
{
if (k == 1)return a;
GF Gnext;
Gnext = db(a);
//cout << "2"; show(Gnext);
if (k == 2)return Gnext;int i1 = 3;
for (int i = 0; Gnext.xn != a.xn&&i1<=k; i++)
{
Gnext = ad(a, Gnext);
//cout << i1 ; show(Gnext);
i1++;
}
return Gnext;
}
bitset<8> Ecc::encrypt(bitset<8> &plain)
{
//cout << "encrypt"<<plain[0]<<" "<<plain << endl;
bitset<4>p1,p2; bitset<8>cipher;
for (int i = 0; i < 8; i++)
{
if (i < 4)
p2[i] = plain[i];
else
{
p1[i - 4] = plain[i];
}
}
bitset<4>c1, c2;
c1 = g[(find(p1) + find(cipher1.x2)) % 15];
c2 = g[(find(p2) + find(cipher1.x2)) % 15];
for (int i = 0; i < 4; i++)
cipher[4+ i] = c1[i];
for (int i = 0; i < 4; i++)
{
cipher[ i] = c2[i];
}
//cout << "cipher:"<<cipher << endl;
return cipher;
}
bitset<8> Ecc::decrypt(bitset<8>&cipher)
{
//cout << "decrypt" << endl;
bitset<8>plain;
bitset<4>p1, p2;
for (int i = 0; i < 8; i++)
{
if (i < 4)
p2[i] = cipher[i];
else
{
p1[i - 4] = cipher[i];
}
}
bitset<4>c1, c2;
//cout << "p1" << p1 << "p2" << " " << p2<<endl;
if (find(p1) > find(plain1.x2))
{
c1 = g[find(p1) - find(plain1.x2)];
}
else
{
c1 = g[15+(find(p1) - find(plain1.x2))];
}
if (find(p2) > find(plain1.x2))
{
c2 = g[find(p2) - find(plain1.x2)];
}
else
{
c2 = g[15+(find(p2) - find(plain1.x2))];
}
for (int i = 0; i < 4; i++)
plain[4 + i] = c1[i];
for (int i = 0; i < 4; i++)
{
plain[i] = c2[i];
}
return plain;
}
GF Ecc::db(GF a)
{
GF next;
bitset<4> langDa; bitset<4> a1 = ellipse_c;
bitset<4>x2, y2;
/*找到langda的值
*/
int p, q; int langda;
p = (a.xn * 2)%15-a.xn;
if (p < 0)p = 15 + p;
q = a.yn - a.xn;
if (q < 0)q = 15 + q;
langDa = g[p] ^ g[q];
langda = find(langDa);
x2 = g[(langda * 2) % 15] ^ g[langda] ^ a1;
next.x = x2;
next.xn = find(x2);
y2 = g[(a.xn * 2) % 15] ^ g[(langda + next.xn) % 15] ^ g[next.xn];
next.y = y2;
next.yn = find(y2);
return next;
}
GF Ecc::ad(GF A, GF B)
{
GF next;
bitset<4> langDa; bitset<4> a1 = ellipse_c;
bitset<4>x3, y3; bitset<4>tempx, tempy;
int p, q; int langda;
tempy = A.y^B.y; p = find(tempy);
tempx = A.x^B.x; q = find(tempx);
int w = p - q;
if (w < 0)w = 15 + w;
langDa = g[w]; langda = w;
x3 = g[(langda * 2) % 15] ^ g[langda] ^ g[A.xn] ^ g[B.xn] ^ a1;
next.x = x3;
next.xn = find(x3);
if (next.xn == 16)
{
y3 = g[(langda + A.xn) % 15] ^ g[A.yn];
next.y = y3;
next.yn = find(y3);
}
else
{
y3 = g[(langda + A.xn) % 15] ^ g[(langda + next.xn) % 15] ^ g[next.xn] ^ g[A.yn];
next.y = y3;
next.yn = find(y3);
}
return next;
}
int Ecc::find(bitset<4> num )
{
int i;
for (i = 0; i < 16; i++)
{
if(num==g[i])
{
//cout << "cout" << num << " " << g[i] << " " << i << endl;
return i;
}
}
return i;
}
void Ecc::use(const char message[])
{
int mg_n = strlen(message);
for (int i = 0; i < mg_n; i++)
{
charToBitset(message[i]);
}
//showList(m);
GF FT;
list<GF>::iterator ListIterator;
FT.x = 6;FT.xn = 5;
FT.y = 14; FT.yn = 11;
calu(FT);
//cout << G.size() << endl;
n= G.size();
srand(time(NULL));//随机获取
d = rand() % n + 1;
//d = 5;
int i = 0;
//cout << "d" << d;
for (ListIterator = G.begin(), i; ListIterator != G.end()&i < d; ListIterator++, i++)
{
Q = *ListIterator;
}
//cout <<"Q.xn:" <<Q.xn<<" "<<Q.yn << endl;
//以上的已经成功调试
//system("pause");
int k = rand() % n + 1;
//int k = 3;
GF dot;
i = 0;
for (ListIterator = G.begin(), i; ListIterator != G.end()&i < k; ListIterator++, i++)
{
dot = *ListIterator;
//cout << "dot:" << dot.x << " " << dot.y << endl;
}
cipher1.x1 = dot.x;
cipher1.y1 = dot.y;
dot = calu(Q, k);
cipher1.x2 = dot.x;
cipher1.y2 = dot.y;
//#cout << "cipher1 " << cipher1.x1 <<" " << cipher1.y1 <<" "<< cipher1.x2<<" " << cipher1.y2 << endl;
plain1.x1 = cipher1.x1;
plain1.y1 = cipher1.y1;
GF W;
W.x = plain1.x1; W.y = plain1.y1;
W.xn = find(W.x); W.yn = find(W.y);
//#cout << "show w"; show(W);
dot = calu(W, d);
plain1.x2 = dot.x;
plain1.y2 = dot.y;
//cout << "plain1 " << plain1.x1 << " " << plain1.y1 << " " << plain1.x2 << " " << plain1.y2 << endl;
//system("pause");
list<bitset<8>>::iterator ListIterator2;
for (ListIterator2 = m.begin(); ListIterator2 != m.end(); ListIterator2++)
sec.push_back(encrypt(*ListIterator2));
//cout << "sec" ; showList(sec);
for (ListIterator2 = sec.begin(); ListIterator2 != sec.end(); ListIterator2++)
c_m.push_back(decrypt(*ListIterator2));
//cout << "c_m"; showList(c_m);
bitsetToString();
//cout << str_plain;
}
void Ecc::show(GF a)
{
cout<< " " << a.xn << " " << a.yn << " " << a.x << " " << a.y << endl;//
}
bitset<8> Ecc::charToBitset(const char s)
{
bitset<8> bits;
for (int i = 0; i<8; ++i)
bits[i] = ((s >> i) & 1);
m.push_back(bits);
return bits;
}
void Ecc::showList(list<bitset<8>> L)
{
list<bitset<8>>::iterator ListIterator2;
for (ListIterator2 = L.begin(); ListIterator2 != L.end(); ListIterator2++)
cout << *ListIterator2 << " ";
cout << endl;
}
string Ecc::bitsetToString()
{
list<bitset<8>>::iterator ListIterator2;
for (ListIterator2 = c_m.begin(); ListIterator2 != c_m.end(); ListIterator2++)
{
char a;
bitset<8>a1 = *ListIterator2;
int a2 = a1.to_ulong();
a = a2;
str_plain = str_plain + a;
}
//for (ListIterator2 = sec.begin(); ListIterator2 != sec.end(); ListIterator2++)
return str_plain;
}
//main.cpp
#include"Euclidean_Algorithm.h"
#include"des.h"
#include"rsa.h"
#include"ecc.h"
#include"sha_1.h"
#include"dss.h"
#include"rc4.h"
#include"rc42.h"
int main()
{
//Gcd a;
//cout<<"1欧几里得:"<<a.gcd(1970, 1066)<<endl;
//cout << "2扩展求欧几里得+逆元:"; cout << a.Euclidean_a << a.e_gcd(1970, 1066);cout<< "+" << a.Euclidean_a << a.e_gcd(550, 1769) << endl;
//cout << "3扩展求逆元,并欧几里得:" <<a.Euclidean_a<<a.extern_gcd(1769,550)<< endl;
//Des des_xiong;
//cout << des_xiong.title << endl;
string s = "computer123"; string k = "1234";
//des_xiong.use(s.c_str(), k.c_str());
//cout << des_xiong.Str_plain << endl;
//list<bitset<32>>::iterator a; bitset<32>q;
//list<bitset<64>>::iterator ListIterator;
//bitset<64>a1;
//for (ListIterator = des_xiong.cipher.begin(); ListIterator != des_xiong.cipher.end(); ++ListIterator)
//{
// a1 = *ListIterator;
// //des_xiong.Str_cipher = des_xiong.Str_cipher + a1.to_string();//二进制密文
// cout << "二进制密文" << a1 << endl;
// for (int i = 1; i >=0; i--)
// {
// bitset<32>temp;
// for (int j = 0; j < 32; j++)
// {
// temp[j] = a1[i * 32 + j];
// }
// cout << temp << " ";
// }
// cout << endl;
//}
//des_xiong.use(s.c_str(), k.c_str());
//cout << des_xiong.Str_plain << endl;
//Rsa rsa_xiong;
//cout << rsa_xiong.title << endl;
//s = "kskjaf";
//rsa_xiong.use(s.c_str( ));
//cout << rsa_xiong.Str_plain << endl;
Ecc ecc_xiong;
cout<<ecc_xiong.title<<endl;
s = "msfassfsafsasf";
ecc_xiong.use(s.c_str());
cout << ecc_xiong.str_plain << endl;
//sha sha_xiong;
//cout << sha_xiong.title << endl;
//s = "abc";
//sha_xiong.use(s.c_str());
//rc4 rc_xiong;
//rc_xiong.use();
//
//rc42 rc2_x;
//cout << rc2_x.title << endl;
//s = "abcdefg";
///rc2_x.use(s.c_str());
//cout << rc2_x.str_plain << endl;
//dss dss1;
//cout<<dss1.title << endl;
//dss1.use(s.c_str());
system("pause");
return 0;
}
做的时候用控制台系统进行封装,使用MFC实现图形化界面。上传进csdn资源中。
如果后续有时间。
需要对ECC的补充,关于选取椭圆曲线,加密的密钥等等。
RSA,实现大数,和自由选取素数。
RC4的学习。