SHA512


#include <iostream> #include <string.h> #include <math.h> using namespace std; #define REG_A "6A09E667F3BCC908" #define REG_B "BB67AE8584CAA73B" #define REG_C "3C6EF372FE94F82B" #define REG_D "A54FF53A5F1D36F1" #define REG_E "510E527FADE682D1" #define REG_F "9B05688C2B3E6C1F" #define REG_G "1F83D9ABFB41Bd6B" #define REG_H "5BE0CD19137E2179" char WHEXADECIMAL[80][17] = {"428a2f98d728ae22", "7137449123ef65cd", "b5c0fbcfec4d3b2f", "e9b5dba58189dbbc", "3956c25bf348b538", "59f111f1b605d019", "923f82a4af194f9b", "ab1c5ed5da6d8118", "d807aa98a3030242", "12835b0145706fbe", "243185be4ee4b28c", "550c7dc3d5ffb4e2", "72be5d74f27b896f", "80deb1fe3b1696b1", "9bdc06a725c71235", "c19bf174cf692694", "e49b69c19ef14ad2", "efbe4786384f25e3", "0fc19dc68b8cd5b5", "240ca1cc77ac9c65", "2de92c6f592b0275", "4a7484aa6ea6e483", "5cb0a9dcbd41fbd4", "76f988da831153b5", "983e5152ee66dfab", "a831c66d2db43210", "b00327c898fb213f", "bf597fc7beef0ee4", "c6e00bf33da88fc2", "d5a79147930aa725", "06ca6351e003826f", "142929670a0e6e70", "27b70a8546d22ffc", "2e1b21385c26c926", "4d2c6dfc5ac42aed", "53380d139d95b3df", "650a73548baf63de", "766a0abb3c77b2a8", "81c2c92e47edaee6", "92722c851482353b", "a2bfe8a14cf10364", "a81a664bbc423001", "c24b8b70d0f89791", "c76c51a30654be30", "d192e819d6ef5218", "d69906245565a910", "f40e35855771202a", "106aa07032bbd1b8", "19a4c116b8d2d0c8", "1e376c085141ab53", "2748774cdf8eeb99", "34b0bcb5e19b48a8", "391c0cb3c5c95a63", "4ed8aa4ae3418acb", "5b9cca4f7763e373", "682e6ff3d6b2b8a3", "748f82ee5defb2fc", "78a5636f43172f60", "84c87814a1f0ab72", "8cc702081a6439ec", "90befffa23631e28", "a4506cebde82bde9", "bef9a3f7b2c67915", "c67178f2e372532b", "ca273eceea26619c", "d186b8c721c0c207", "eada7dd6cde0eb1e", "f57d4f7fee6ed178", "06f067aa72176fba", "0a637dc5a2c898a6", "113f9804bef90dae", "1b710b35131c471b", "28db77f523047d84", "32caab7b40c72493", "3c9ebe0a15c9bebc", "431d67c49c100d4c", "4cc5d4becb3e42b6", "597f299cfc657e2a", "5fcb6fab3ad6faec", "6c44198c4a475817" }; /* 十六进制转二进制 */ string Hex2Bin(const string hex){ string binary; for(int i = 0; i < 16; i++){ if(hex[i] == '0') binary += "0000"; else if(hex[i] == '1') binary += "0001"; else if(hex[i] == '2') binary += "0010"; else if(hex[i] == '3') binary += "0011"; else if(hex[i] == '4') binary += "0100"; else if(hex[i] == '5') binary += "0101"; else if(hex[i] == '6') binary += "0110"; else if(hex[i] == '7') binary += "0111"; else if(hex[i] == '8') binary += "1000"; else if(hex[i] == '9') binary += "1001"; else if(hex[i] == 'a' || hex[i] == 'A') binary += "1010"; else if(hex[i] == 'b' || hex[i] == 'B') binary += "1011"; else if(hex[i] == 'c' || hex[i] == 'C') binary += "1100"; else if(hex[i] == 'd' || hex[i] == 'D') binary += "1101"; else if(hex[i] == 'e' || hex[i] == 'E') binary += "1110"; else if(hex[i] == 'f' || hex[i] == 'F') binary += "1111"; else return NULL; } return binary; } /* 二进制转十六进制 */ string Bin2Hex(string bin,int n){ string hex; int count = n/4; for(int i = 0; i < count; i++){ char mid[4]; for(int r = 0; r < 4; r++){ mid[r] = bin[i*4+r]; } if(strcmp(mid,"0000") == 0) hex += "0"; else if(strcmp(mid,"0001") == 0) hex += "1"; else if(strcmp(mid,"0010") == 0) hex += "2"; else if(strcmp(mid,"0011") == 0) hex += "3"; else if(strcmp(mid,"0100") == 0) hex += "4"; else if(strcmp(mid,"0101") == 0) hex += "5"; else if(strcmp(mid,"0110") == 0) hex += "6"; else if(strcmp(mid,"0111") == 0) hex += "7"; else if(strcmp(mid,"1000") == 0) hex += "8"; else if(strcmp(mid,"1001") == 0) hex += "9"; else if(strcmp(mid,"1010") == 0) hex += "a"; else if(strcmp(mid,"1011") == 0) hex += "b"; else if(strcmp(mid,"1100") == 0) hex += "c"; else if(strcmp(mid,"1101") == 0) hex += "d"; else if(strcmp(mid,"1110") == 0) hex += "e"; else if(strcmp(mid,"1111") == 0) hex += "f"; else return NULL; } return hex; } /* 十进制转二进制 */ void Dec2Bin(int Dec, string &binary){ int n = Dec,j = 0; while(n > 0){ char s[8]; sprintf(s, "%d", n%2); binary += s; n /= 2; j++; } int len = binary.length(); for(int i = 0; i < len/2; i++){ char temp = binary[i]; binary[i] = binary[len-i-1]; binary[len-i-1] = temp; } } /* 字符串转换成二进制 */ string Str2Bin(string data) { string h0; for(int i = 0; data[i]; i++){ char c = data[i]; unsigned char k = 0x80; for (int i=0; i<8; i++, k >>= 1){ if (c & k){ h0 += "1"; }else{ h0 += "0"; } } } return h0; }

sha512.cpp

#include "constant.hpp"


void AddP(string &h0, int n){
    h0 += "1";
    for(int i = 0; i < n-1; i++){
        h0 += "0";
    }
}

/* 按位进行模2加(异或) */
string mod2(string a, string b){
    string res;
    int len = a.length();
    for(int i = 0; i < len; i++){
        if(a[i] == b[i])
            res += "0";
        else 
            res += "1";
    }
    return res;
}

/* 补全明文内容 */
void Completion(string &h0){
    int len = h0.length();
    string add;
    /* 附加填充位 */
    int remainder = h0.length()%1024;
    if(remainder != 896)
        AddP(h0, 896-remainder);
    else
        AddP(h0, 1024);

    /* 附加长度 */
    string L;
    Dec2Bin(len, L);
    if(L.length() == 128)
        h0 += L;
    else{
    for(int i = 0; i < (128-L.length()); i++)
        h0 += "0";
    h0 += L;
    }
}


/* 初始化a,b,c,d,e,f,g,h */
void InitRegis(string &a, string &b, string &c, string &d, string &e, string &f, string &g, string &h){
    a = Hex2Bin(REG_A);
    b = Hex2Bin(REG_B);
    c = Hex2Bin(REG_C);
    d = Hex2Bin(REG_D);
    e = Hex2Bin(REG_E);
    f = Hex2Bin(REG_F);
    g = Hex2Bin(REG_G);
    h = Hex2Bin(REG_H);
}


/* x循环右移n位 */
string ROTR(string x, int n){
    string str1 = x.substr(0, 64-n);
    string str2 = x.substr(64-n, n);
    return str2+str1;
}

/* 右移n位,左边填充0 */
string SHR(string x, int n){
    string str1 = x.substr(0, 64-n);
    string str2;
    for(int i = 0; i < n; i++){
        str2 += "0";
    }
    return str2+str1;
}


/* 模2^64位加 */
string mod2_64(string a, string b){
    string res;
    long long int n = 0;
    for(long long int i=60; i>=0;i-=8){
        string add;
        long long int fir = 0,sec = 0,left = 0;
        for(long long int j=0;j<4;j++,i++){
            if(a[i]=='1')
                fir+=pow(2.0,3-j);
            if(b[i]=='1')
                sec += pow(2.0,3-j);
        }
        left = (fir+sec+n)%16;
        n = (fir+sec+n-left)/16;
        Dec2Bin(left,add);
        if(add.length() == 4)
            res = add+res;
        else{
            long long int len = add.length();
            for(long long int r = 0; r < (4-len); r++)
            add = "0"+add;
            res = add+res;
        }
    }
    return res;
}


/* 获取输入序列Wt */
void GetW(string M, int i, string* Wi){
    string res,sigma1,sigma0;
    if(i < 16){
        Wi[i] = M.substr(i*64, 64);
    }else{
        string a = mod2(ROTR(Wi[i-2], 19), ROTR(Wi[i-2], 61));
        sigma1 = mod2(a, SHR(Wi[i-2], 6));   
        string b = mod2(ROTR(Wi[i-15], 1), ROTR(Wi[i-15], 8));
        sigma0 = mod2(b, SHR(Wi[i-15], 7)); 
        res = mod2_64(sigma1, Wi[i-7]);
        string mid = mod2_64(res, sigma0);
        res = mod2_64(mid, Wi[i-16]);
        Wi[i] = res;
    }
}


/* Ch(e,f,g) */
string Ch(string e, string f, string g){
    string res;
    int len = e.length();
    for(int i = 0; i < len; i++){
        if(e[i] == '1')
            res += f[i];
        else
            res += g[i];
    }
    return res;
}

/* Maj(a,b,c) */
string Maj(string a, string b, string c){
    string res;
    int selection;
    int len = a.length();
    for(int i = 0; i < len; i++){
        selection = (a[i]-48) + (b[i]-48) + (c[i]-48);
        if(selection >= 2)
            res += "1";
        else
            res += "0";
    }
    return res;
}

/* 轮函数 */
void Round(string M, string &a, string &b, string &c, string &d, string &e, string &f, string &g, string &h){
    string K,Sum512_1,Sum512_0,Ch_efg,Maj_abc,T1,T2,mid;
    string Wi[80];
    /* 80轮运算模块 */
    for(int j = 0; j < 80; j++){
        /* T1 */
        GetW(M, j, Wi);    
        string k = WHEXADECIMAL[j];
        K = Hex2Bin(k);
        mid = mod2(ROTR(e, 14), ROTR(e, 18));
        Sum512_1 = mod2(mid, ROTR(e, 41));
        mid = mod2(ROTR(a, 28), ROTR(a, 34));
        Sum512_0 = mod2(mid, ROTR(a, 39));
        Ch_efg = Ch(e, f, g); 
        Maj_abc = Maj(a, b, c);

        T1 = mod2_64(h, Ch_efg);
        mid = mod2_64(T1, Sum512_1);
        T1 = mod2_64(mid, Wi[j]);
        mid = mod2_64(T1, K);
        T1 = mid;
            
        /* T2 */
        T2 = mod2_64(Sum512_0, Maj_abc);
        h = g;
        g = f;
        f = e;
        e = mod2_64(d, T1);
        d = c;
        c = b;
        b = a;
        a = mod2_64(T1, T2);
    }
}

int main()
{
    /* 明文 */
    cout << "输入文本:" << endl;
    string data;
    cin >> data;
    /* 字符串模拟二进制形式 */
    string h0 = Str2Bin(data);
    /* 补全h0 */
    Completion(h0);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    /* 初始化abcdefgh */
    string a,b,c,d,e,f,g,h;
    InitRegis(a,b,c,d,e,f,g,h);
    string H1,H2,Hi;
    /* 主循环次数 */
    int N = h0.length()/1024;
    for(int i = 0; i < N; i++){
        string M = h0.substr(i*1024, 1024);
        /* 记录H(i-1)的值 */
        string A=a,B=b,C=c,D=d,E=e,F=f,G=g,H=h;
        Round(M,a,b,c,d,e,f,g,h);

        a = mod2_64(a,A);
        b = mod2_64(b,B);
        c = mod2_64(c,C);
        d = mod2_64(d,D);
        e = mod2_64(e,E);
        f = mod2_64(f,F);
        g = mod2_64(g,G);
        h = mod2_64(h,H);
        A = a;
        B = b;
        C = c;
        D = d;
        E = e;
        F = f;
        G = g;
        H = h;
    }
    string result = Bin2Hex(a+b+c+d+e+f+g+h,64*8);
    cout << "摘要结果:" << result << endl;
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/threewater/p/11130602.html