首页 > 其他 > 详细

安全编程项目

时间:2021-04-05 17:20:16      阅读:13      评论:0      收藏:0      [点我收藏+]

\(\textbf{Proj1. Miller-Rabin}\)

\(\textbf{Big Decimal}\)

大整数加减乘除取模,非负数运算可以保证正确率,负数运算不保证准确率,乘法没有使用快速傅里叶变换加速,自从学了 \(FFT\) 之后感觉实现较难,所以没有花精力嵌入大整数模板,属于低级轮子

#include <bits/stdc++.h>
using namespace std;

int cmp(string A, string B);
string operator + (const string& a, const string& b);
string operator - (const string& a, const string& b);
string operator * (const string& a, const string& b);
string operator / (const string& a, const string& b);
string operator % (const string& a, const string& b);

int main()
{
    freopen("in.txt", "r", stdin);
    string s1, s2, s3, s4, s5, s6, s7;
    int f = 0;
    while (cin >> s1 >> s2 >> s3 >> s4 >> s5 >> s6 >> s7) {
        int f[5] = {0};
        if (s1 + s2 == s3) f[0] = 1;
        if (s1 - s2 == s4) f[1] = 1;
        if (s1 * s2 == s5) f[2] = 1;
        if (s1 / s2 == s6) f[3] = 1;
        if (s1 % s2 == s7) f[4] = 1;
        for (int i = 0; i < 5; ++i) {
            if (f[i] == 0) cout << "×";
            else cout << "√";
        }
        cout << endl;
    }
    //puts(!f ? "AC" : "WA");
    return 0;
}


int cmp(string A, string B)
{
    if (A.length() < B.length()) return -1;
    else if (A.length() > B.length()) return 1;
    else {
        for (int i = 0; i < A.length(); ++i) {
            if (A[i] < B[i]) return -1;
            else if (A[i] > B[i]) return 1;
        }
        return 0;
    }
}

string operator + (const string& a, const string& b)
{
    int flag = 0;
    if (a[0] == ‘-‘ && b[0] == ‘-‘) flag = 1; // (-a) + (-b) = -(a + b)
    else if (a[0] == ‘-‘ && b[0] != ‘-‘) return b - a.substr(1, a.length()); // -a + b = b - a
    else if (a[0] != ‘-‘ && b[0] == ‘-‘) return a - b.substr(1, b.length()); // a + (-b) = a - b
    else flag = 0; // a + b
    string A = "", B = "";
    A = flag ? a.substr(1, a.length()) : a;
    B = flag ? b.substr(1, b.length()) : b;
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    if (A.length() < B.length()) swap(A, B);
    int L1 = A.length(), L2 = B.length();
    string C = "";
    int now = 0, up = 0;
    for (int i = 0; i < L1; ++i) {
        if (i < L2) now = up + A[i] - ‘0‘ + B[i] -‘0‘;
        else now = up + A[i] - ‘0‘;
        up = now / 10;
        now %= 10;
        C += now + ‘0‘;
    }
    while (up) C += up % 10 + ‘0‘, up /= 10;
    if (flag) C += ‘-‘;
    reverse(C.begin(), C.end());
    return C;
}

string operator - (const string& a, const string& b)
{
    string A = "";
    string B = "";
    if (a[0] == ‘-‘ && b[0] == ‘-‘) { // -a - (-b) = b - a
        A = a.substr(1, a.length());
        B = b.substr(1, b.length());
        return B - A;
    }
    else if (a[0] == ‘-‘ && b[0] != ‘-‘) { // -a - b = (-a) + (-b)
        A = a;
        B = b;
        return (A + B).insert(0, "-");
    }
    else if (a[0] != ‘-‘ && b[0] == ‘-‘) { // a - (-b) = a + b
        A = a;
        B = b.substr(1, b.length());
        return A + B;
    }
    else { // a - b
        A = a, B = b;
        int flag = 0;
        if (cmp(A, B) == -1) swap(A, B), flag = 1;
        reverse(A.begin(), A.end());
        reverse(B.begin(), B.end());
        int L1 = A.length(), L2 = B.length();
        int now = 0, lend = 0;
        string C = "";
        for (int i = 0; i < L1; ++i) {
            if (i < L2) now = lend + (A[i] - ‘0‘) - (B[i] - ‘0‘);
            else now = lend + (A[i] - ‘0‘);
            if (now < 0) now += 10, lend = -1;
            else lend = 0;
            C += now + ‘0‘;
        }
        int pos = C.length() - 1;
        while (C[pos] == ‘0‘ && pos > 0) --pos;
        C = C.substr(0, pos + 1);
        if (flag) C += ‘-‘;
        reverse(C.begin(), C.end());
        return C;
    }
}

string operator * (const string& a, const string& b)
{
    int flag = 0;
    if (a[0] == ‘-‘ && b[0] == ‘-‘) flag = 0;
    else if (a[0] == ‘-‘ && b[0] != ‘-‘) flag = 1;
    else if (a[0] != ‘-‘ && b[0] == ‘-‘) flag = 1;
    else flag = 0;
    string A = a[0] == ‘-‘ ? a.substr(1, a.length()) : a;
    string B = b[0] == ‘-‘ ? b.substr(1, b.length()) : b;
    reverse(A.begin(), A.end());
    reverse(B.begin(), B.end());
    if (A.length() < B.length()) swap(A, B);
    int L1 = A.length(), L2 = B.length();
    vector<int> arr(L1 + L2, 0);
    for (int i = 0; i < L1; ++i)
        for (int j = 0; j < L2; ++j)
            arr[i + j] += (A[i] - ‘0‘) * (B[j] - ‘0‘);
    string C = "";
    int up = 0;
    for (int i = 0; i < L1 + L2; ++i) {
        int now = up + arr[i];
        C += now % 10 + ‘0‘;
        up = now / 10;
    }
    while (up) {
        C += up % 10;
        up = up / 10;
    }
    int pos = C.length() - 1;
    while (C[pos] == ‘0‘ && pos > 0) --pos;
    C = C.substr(0, pos + 1);
    if (flag) C += ‘-‘;
    reverse(C.begin(), C.end());
    return C;
}


string operator / (const string& a, const string& b)
{
    string A = a;
    string B = b;
    if (B == "0") return "false";
    if (cmp(A, B) < 0) return "0";
    else if (cmp(A, B) == 0) return "1";
    else {
        int L1 = A.length(), L2 = B.length();
        string C = "";
        string temp = "0";
        for (int i = 0; i < L1; ++i) {
            string x = string(1, A[i]);
            temp = temp + x;
            int cnt = 0;
            while (cmp(temp, B) >= 0) temp = temp - B, cnt++;
            temp = temp * "10";
            C += cnt + ‘0‘;
        }
        int pos = 0;
        while (C[pos] == ‘0‘) pos++;
        return C.substr(pos, C.length() - pos + 1);
    }
}


string operator % (const string& a, const string& b)
{
    if (b == "0") return "false";
    return a - a / b * b;
}

\(\textbf{Miller-Rabin}\)

代码生成 \(10\)120-bit 大素数并输出运行时间,使用 __int128 来代替大整数

#include <bits/stdc++.h>
#define int128 __int128
using namespace std;

string genRandString(int L)
{
    string ans = "";
    ans += ‘1‘;
    for (int i = 0; i < L - 2; ++i) ans += ‘0‘ + rand() % 2;
    ans += ‘1‘;
    return ans;
}

int128 stringToInt(string s)
{
    int128 ans = 0;
    for (int i = 0; i < s.length(); ++i) ans *= 2, ans += s[i] - ‘0‘;
    return ans;
}

string intToString(int128 n)
{
    string s1 = "", s2 = "";
    while (n) {
        s1 += n % 10 + ‘0‘;
        n /= 10;
    }
    for(int i = s1.length() - 1; i >= 0; --i) s2 += s1[i];
    return s2;
}

int128 randInt128(int128 a, int128 b)
{
    mt19937 eng(time(0));
    uniform_int_distribution<int128> dis(a, b);
    return dis(eng);
}

int128 qmul(int128 a, int128 b, int128 p)
{
    int128 ans = 0;
    while (b) {
        if (b & 1) ans += a, ans %= p;
        a += a, a %= p, b >>= 1;
    }
    return ans;
}

int128 qpow(int128 a, int128 b, int128 p)
{
    int128 ans = 1;
    while (b) {
        if (b & 1) ans = qmul(ans, a, p);
        a = qmul(a, a, p), b >>= 1;
    }
    return ans;
}

bool miller_rabin(int128 n, int k)
{
    int128 t = n - 1;
    int s = 0;
    while (t % 2 == 0) t /= 2, s++;
    for (int i = 0; i < k; ++i) {
        int128 a = randInt128(2, n - 2); // 生成 [2, n-2] 中的随机数 a
        //cout << intToString(a) << endl;
        int128 temp = qpow(a, t, n);
        if (temp % n == 1 || temp % n == n - 1) continue; // 本轮检测通过
        int flag = 0;
        for (int j = 1; j < s; ++j) {
            temp = qmul(temp, temp, n);
            if (temp % n == n - 1) {flag = 1; break;}
        }
        if (flag) continue; // 本轮检测通过
        return 0; // 检测不通过
    }
    return 1;
}

bool isPrime(int128 n)
{
    if (n == 1) return 0; // 判断 1
    if (n == 2) return 1; // 判断 2
    if (n % 2 == 0) return 0; // 判断偶数
    int k = 10;
    return miller_rabin(n, k);
}

void solve()
{
    auto s = clock();
    srand((unsigned)time(0));
    int L = 120;
    int cnt = 0;
    while (cnt <= 10) {
        string s = genRandString(L);
        int128 n = stringToInt(s);
        string N = intToString(n);
        //cout << s << endl;
        //cout << N << endl;
        int flag = isPrime(n);
        //puts(flag == 1 ? "Prime" : "Not prime");
        if (flag == 1) {
            cout << N << endl;
            cnt++;
        }
    }
    auto t = clock();
    cout << (double)(t - s) / CLOCKS_PER_SEC << endl;
}

int main()
{
    solve();
    return 0;
}

\(\textbf{Proj2. Stream Cipher}\)

递推出循环节之后分组异或加密

#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
using namespace std;

int dp[15];

void init()
{
    dp[0] = 0, dp[1] = 0, dp[2] = 0, dp[3] = 1;
    for (int i = 4; i < 15; ++i)
        dp[i] = (dp[i - 1] + dp[i - 4]) % 2;
}

string input(string msg)
{
    string ans = "";
    for (int i = 0; i < msg.length(); ++i) {
        char x = msg[i];
        //cout << x << endl;
        string temp = "";
        while (x) {
            temp += x % 2 + ‘0‘;
            x /= 2;
        }
        for (int i = temp.length(); i < 8; ++i) temp += ‘0‘;
        reverse(temp.begin(), temp.end());
        ans += temp;
    }
    return ans;
}

pair<string, string> encry(string msg)
{
    int L = msg.length();
    int x = L / 15, y = L % 15;
    string key = "";
    for (int i = 1; i <= x; ++i)
        for (int j = 0; j < 15; ++j)
            key += dp[j] + ‘0‘;
    for (int i = 0; i < y; ++i)
        key += dp[i] + ‘0‘;
    string cipher = "";
    for (int i = 0; i < L; ++i)
        cipher += ‘0‘ + (msg[i] - ‘0‘) ^ (key[i] - ‘0‘);
    return {cipher, key};
}

string decry(string c, string k)
{
    string temp = "";
    int L = c.length();
    for (int i = 0; i < L; ++i)
        temp += ‘0‘ + (c[i] - ‘0‘) ^ (k[i] - ‘0‘);
    int res = temp[0] - ‘0‘;
    string ans = "";
    for (int i = 1; i <= L; ++i) {
        if (i % 8 == 0) ans += char(res), res = temp[i] - ‘0‘;
        else res = res * 2 + temp[i] - ‘0‘;
    }
    return ans;
}
int main()
{
    init();
    cout << "Please input the cipher text" << endl;
    string s;
    getline(cin, s);
    string msg = input(s);
    pair<string, string> pss = encry(msg);
    string cipher = pss.first;
    string key = pss.second;
    cout << "The cipher text is:\n" << cipher << endl;
    cout << "The key is:\n" << key << endl;
    string plain = decry(cipher, key);
    cout << "The decrypted plain text is:\n" << plain << endl;
    return 0;
}

/*
000111101011001
000101001101110
*/

\(\textbf{Proj3. DES}\)

\(DES\) 加密分为密钥生成,与明文加密,夹杂一系列混淆扩散操作,解密与加密完全一样,只不过密钥的使用顺序反过来

输入明文和密钥,输出密文,并输出解密后的明文

输入的均为 64-bit 的二进制串,输出的均为 16 进制数

#include <bits/stdc++.h>

using namespace std;

// 初始置换表,置换 64 位明文
int IP[] = {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};

// 密钥置换表,将 64 位密钥变成 56 位
int PC_1[] = {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[] = {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[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};

// 扩展置换表,将 bitset<32> 扩展至 bitset<48>
int E[] = {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[] = {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};

// 尾置换表
int IP_inverse[] = {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};

/* 重载 bitset<28> 的加法运算符 */
bitset<56> operator+(const bitset<28> &bt1, const bitset<28> &bt2)
{
    string s1 = bt1.to_string(), s2 = bt2.to_string();
    s1 += s2;
    return bitset<56>(s1);
}

/* 重载 bitset<32> 的加法运算符 */
bitset<64> operator+(const bitset<32> &bt1, const bitset<32> &bt2)
{
    string s1 = bt1.to_string(), s2 = bt2.to_string();
    s1 += s2;
    return bitset<64>(s1);
}

/* 鉴于 bitset 实际下标从低位(从右往左)算起,因此对逻辑下标(从左往右)做一个转换,下标从零开始计数 */
/* input: bitset 的长度 n,逻辑下标 pos */
/* output: 实际下标 */
int TransIndex(int n, int pos)
{
    return n - pos - 1;
}

/* 利用 IP 对输入的 bitset<64> input 进行初始置换 */
/* input: 初始明文 input */
/* output: 置换后的两个 bitset<32> 明文组成的 vector */
vector<bitset<32>> InitialPermutation(const bitset<64> &input)
{
    string str = "";
    for (int i = 0; i < 64; ++i)
        str += input[TransIndex(64, IP[i] - 1)] + ‘0‘;
    string substr1 = str.substr(0, 32);
    string substr2 = str.substr(32, 32);
    vector<bitset<32>> ret;
    ret.emplace_back(bitset<32>(substr1));
    ret.emplace_back(bitset<32>(substr2));
    return ret;
}

/* 利用 PC_1 对输入的 bitset<64> key 进行密钥置换 */
/* input: 密钥 key */
/* output: 置换压缩后的 key */
bitset<56> KeyPermutation(const bitset<64> &key)
{
    string str = "";
    for (int i = 0; i < 56; ++i)
        str += key[TransIndex(64, PC_1[i] - 1)] + ‘0‘;
    return bitset<56>(str);
}

/* 对 bitset<28> 的密钥进行循环左移 */
/* input: bitset<28> key, 左移轮数 round */
/* output: 左移后的 bitset<28> */
bitset<28> LeftShift(const bitset<28> &key, int round)
{
    int shift = shiftBits[round];
    return ((key << shift) | (key >> (28 - shift)));
}

/* 先将输入的 bitset<28> key1, key2 进行拼接,再利用 PC_2 对输入的 bitset<56> 进行密钥压缩 */
/* key1, key2 可修改 */
/* input: 两个子密钥 bitset<28> key1, key2,左移轮数 round */
/* output: 合成压缩后的长度为 48 的密钥 */
bitset<48> GetSubKey(bitset<28> &key1, bitset<28> &key2, int round)
{
    key1 = LeftShift(key1, round);
    key2 = LeftShift(key2, round);
    bitset<56> key = key1 + key2;
    string str = "";
    for (int i = 0; i < 48; ++i)
        str += key[TransIndex(56, PC_2[i] - 1)] + ‘0‘;
    return bitset<48>(str);
}

/* 生成 16 轮密钥 */
/* 每一轮的 subKey1, subKey2 都由上一轮修改给出 */
/* input: 用来存储 16 轮密钥的 vector,初始密钥 bitset<64> key */
/* output: none */
void GenKey(vector<bitset<48>> &K, const bitset<64> &key)
{
    /* 对密钥进行置换 */
    bitset<56> handledKey = KeyPermutation(key);
    bitset<28> subKey1(handledKey.to_string().substr(0, 28));
    bitset<28> subKey2(handledKey.to_string().substr(28, 28));
    /* 生成每一轮的密钥 */
    for (int i = 1; i <= 16; ++i) {
        bitset<48> subKey = GetSubKey(subKey1, subKey2, i - 1);
        K[i] = subKey;
    }
}

/* 用每一轮的密钥加密每一轮的输入 */
/* input: 每一轮的输入明文 input, 每一轮的密钥 key */
/* output: 每一轮的密文 */
bitset<32> func(const bitset<32> &input, const bitset<48> &key)
{
    /* 生成 bitset<48> 扩展明文 */
    string str = "";
    for (int i = 0; i < 48; ++i) str += input[TransIndex(32, E[i] - 1)] + ‘0‘;
    bitset<48> expandedInput(str);

    /* 生成异或值 */
    bitset<48> xorRes = expandedInput ^key;

    /* 将异或值分成 8 组 bitset<6> */
    vector<bitset<6>> xorResGroup(8);
    string temp = "";
    for (int i = 47; i >= 0; --i) {
        temp += xorRes[i] + ‘0‘;
        if (i % 6 == 0) {
            xorResGroup[i / 6] = bitset<6>(temp);
            temp = "";
        }
    }
    reverse(xorResGroup.begin(), xorResGroup.end());

    /* 根据 bitset<6> 查询 S 盒,转化为 8 组 bitset<4> */
    vector<bitset<4>> retGroup(8);
    for (int i = 0; i < 8; ++i) {
        bitset<6> xorResGroupMember = xorResGroup[i];
        int x = 0, y = 0;
        for (int j = 5; j >= 0; --j) { // 根据秦九韶算法从高位往第位计算
            if (j == 0 || j == 5) x *= 2, x += xorResGroupMember[j];
            else y *= 2, y += xorResGroupMember[j];
        }
        int target_val = S_BOX[i][x][y];
        bitset<4> retGroupMember(target_val);
        retGroup[i] = retGroupMember;
    }

    /* 将 8 组 bitset<4> 组成 bitset<32> */
    str = "";
    for (int i = 0; i < 8; ++i) {
        str += retGroup[i].to_string();
    }
    string str2 = "";

    /* 对输出的 bitset<32> 进行 P 置换 */
    for (int i = 0; i < 32; ++i)
        str2 += str[P[i] - 1];
    return bitset<32>(str2);
}

/* 将 bitset<32> L, R 合并后逆置换输出 */
/* input: bitset<32> L, R */
/* output: 合并并且逆置换后的 bitset<64> 结果*/
bitset<64> InversePermutation(bitset<32> &L, bitset<32> &R)
{
    bitset<64> res = L + R;
    string str = "";
    for (int i = 0; i < 64; ++i)
        str += res[TransIndex(64, IP_inverse[i] - 1)] + ‘0‘;
    return bitset<64>(str);
}

/* 加密 */
/* input: 明文 message,密钥 key*/
/* output: 密文 */
bitset<64> Encrypt(const bitset<64> &message, const vector<bitset<48>> &K)
{
    /* 置换明文 */
    vector<bitset<32>> handledMessage = InitialPermutation(message);

    /* 生成 16 轮 L, R */
    vector<bitset<32>> L(17);
    vector<bitset<32>> R(17);
    L[0] = handledMessage[0];
    R[0] = handledMessage[1];
    for (int i = 1; i <= 16; ++i) {
        L[i] = R[i - 1];
        R[i] = L[i - 1] ^ func(R[i - 1], K[i]);
    }

    /* 逆置换明文 */
    bitset<64> ret = InversePermutation(R[16], L[16]);
    return ret;
}

/* 解密 */
/* input: 密文 message,密钥 key*/
/* output: 明文 */
bitset<64> Decrypt(const bitset<64> &secret, const vector<bitset<48>> &K)
{
    /* 置换明文 */
    vector<bitset<32>> handledMessage = InitialPermutation(secret);

    /* 生成 16 轮 L, R */
    vector<bitset<32>> L(17);
    vector<bitset<32>> R(17);
    L[0] = handledMessage[0];
    R[0] = handledMessage[1];
    for (int i = 1; i <= 16; ++i) {
        L[i] = R[i - 1];
        R[i] = L[i - 1] ^ func(R[i - 1], K[17 - i]);
    }

    /* 逆置换明文 */
    bitset<64> ret = InversePermutation(R[16], L[16]);
    return ret;
}

/* 二进制转十六进制 */
/* input: 二进制串 */
/* output: 十六进制串 */
string Bin2Hex(string Bin)
{
    string Hex = "0x";
    int temp = Bin[0] - ‘0‘;
    for (int i = 1; i <= Bin.length(); ++i) {
        if (i % 4 == 0) {
            Hex += temp >= 10 ? temp - 10 + ‘a‘ : temp + ‘0‘;
            temp = 0;
        }
        if (i < Bin.length()) temp *= 2, temp += Bin[i] - ‘0‘;
    }
    return Hex;
}


int main()
{
    bitset<64> m("0111001001101111011011010110000101101110011101000110100101100011");
    bitset<64> k("0001001100110100010101110111100110011011101111001101111111110001");

    /* 生成 16 轮 key */
    vector<bitset<48>> K(17);
    GenKey(K, k);

    cout << "input:               " << Bin2Hex(m.to_string()) << endl;
    cout << "key:                 " << Bin2Hex(k.to_string()) << endl;

    bitset<64> secret = Encrypt(m, K);
    bitset<64> plaintext = Decrypt(secret, K);
    cout << "secret:              " << Bin2Hex(secret.to_string()) << endl;
    cout << "Decrypted plaintext: " << Bin2Hex(plaintext.to_string()) << endl;

    return 0;
}

安全编程项目

原文:https://www.cnblogs.com/ChenyangXu/p/14618591.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!