2017-07-28 1 views
1

Ich brauche ein paar Versionen von SHA in C++, meist von Grund auf für ein Sommerlager. Here's the docs for the algorithm.C++ - Implementierung von SHA-512 funktioniert nicht

Ich habe SHA-1, SHA-224 und SHA-256 funktioniert perfekt, aber ich habe es nicht geschafft 512 oder seine Derivate richtig zu bekommen. Ich soll ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a 2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f bekommen, aber mein Programm gibt mir 21fb47208172306 4570d403444f23d 3fcab6a24097aaf4 7920558b5eea0ae8 7cfc6ce26543e3a6 8ba9c07d1b89d02 1e27ad9d5487df13 2e4a745e0e4df60.

main.cpp:

#include "main.h" 
#include <iostream> 
#include <iomanip> 
#include <sstream> 
int main(int argc, const char * argv[]) { 
    std::string msg = "abc"; 
    std::string hashedMsg = hash(msg); 
    std::cout << "Hash:" << std::endl << hashedMsg; 
    std::cin.get(); 
} 
std::string hash(std::string msg) 
{ 
    //Preprocessing 
    const unsigned char eighty = 0x80; 
    unsigned long long msgLength = msg.length() * 8; 
    unsigned long long msgBitSize = _byteswap_uint64(msgLength); 
    unsigned long long k = 1024 - ((msgLength + 64 + 1) % 1024); 
    unsigned long long finalSize = msgLength + 1 + k + 64; 
    unsigned long long hashValues[] = { 
     0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 
     0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 
    }; 
    std::vector<unsigned long long> words(finalSize/64); 
    std::memcpy(words.data(), msg.c_str(), msg.length()); 
    std::memcpy((unsigned char *)words.data() + msg.length(), &eighty, 1); 
    std::memcpy((unsigned char *)words.data() + msg.length()+1+((k-7)/8), &msgBitSize, 8); 
    unsigned char* byte = (unsigned char*)words.data(); 
    for (int i = 0; i < words.size() * 8; i++) { 
     std::bitset<8> b(byte[i]); 
     std::cout << b << " " << std::hex << std::setfill('0') << std::setw(2) << (int)byte[i] << std::endl; 
    } 
    // Processing 
    unsigned long long workingValues[8]; 
    unsigned long long a; 
    unsigned long long b; 
    unsigned long long c; 
    unsigned long long d; 
    unsigned long long e; 
    unsigned long long f; 
    unsigned long long g; 
    unsigned long long h; 
    unsigned long long temp1; 
    unsigned long long temp2; 
    for (int chunk = 0; chunk < words.size(); chunk += 16) { 
     std::vector<unsigned long long> schedule(80); 
     for (int i = 0; i < 16; i++) { 
      schedule[i] = _byteswap_uint64(words[chunk + i]); 
     } 
     for (int i = 16; i < 80; i++) { 
      schedule[i] = (s1(schedule[i - 2]) + schedule[i - 7] + s0(schedule[i - 15]) + schedule[i - 16]) % (long long)(pow(2, 64)); 
     } 
     for (int i = 0; i < 8; i++) { 
      workingValues[i] = hashValues[i]; 
     } 
     a = workingValues[0]; 
     b = workingValues[1]; 
     c = workingValues[2]; 
     d = workingValues[3]; 
     e = workingValues[4]; 
     f = workingValues[5]; 
     g = workingValues[6]; 
     h = workingValues[7]; 
     for (int t = 0; t < 80; t++) { 
      temp1 = (h + S1(e) + ch(e, f, g) + sha::words[t] + schedule[t]) % (long long)(pow(2, 64)); 
      temp2 = (S0(a) + maj(a, b, c)) % (long long)(pow(2, 64)); 
      h = g; 
      g = f; 
      f = e; 
      e = (d + temp1) % (long long)(pow(2, 64)); 
      d = c; 
      c = b; 
      b = a; 
      a = (temp1 + temp2) % (long long)(pow(2, 64)); 
     } 
     hashValues[0] = (hashValues[0] + a) % (long long)(pow(2, 64)); 
     hashValues[1] = (hashValues[1] + b) % (long long)(pow(2, 64)); 
     hashValues[2] = (hashValues[2] + c) % (long long)(pow(2, 64)); 
     hashValues[3] = (hashValues[3] + d) % (long long)(pow(2, 64)); 
     hashValues[4] = (hashValues[4] + e) % (long long)(pow(2, 64)); 
     hashValues[5] = (hashValues[5] + f) % (long long)(pow(2, 64)); 
     hashValues[6] = (hashValues[6] + g) % (long long)(pow(2, 64)); 
     hashValues[7] = (hashValues[7] + h) % (long long)(pow(2, 64)); 
    } 
    // Return final message 
    std::stringstream ss; 
    for (int i = 0; i < 8; i++) { 
     ss << std::hex << hashValues[i]; 
    } 
    return ss.str(); 
} 

main.h:

#pragma once 
#include<string> 
#include<vector> 
#include<bitset> 
namespace sha { 
    const unsigned long long words[] = { 
     0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 
     0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 
     0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 
     0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, 
     0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 
     0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 
     0x983e5152ee66dfab, 0xa831c66d2db, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 
     0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, 
     0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 
     0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 
     0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 
     0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 
     0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 
     0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 
     0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, 
     0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 
     0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 
     0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, 
     0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, 
     0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 
    }; 
} 
std::string hash(std::string msg); 
unsigned long long rotr(unsigned long long x, unsigned int n) { 
    return (x >> n) | (x << (32 - n)); 
} 
unsigned long long ch(unsigned long long e, unsigned long long f, unsigned long long g) { 
    return (e & f)^((~e) & g); 
} 
unsigned long long maj(unsigned long long a, unsigned long long b, unsigned long long c) { 
    return (a & b)^(a & c)^(b & c); 
} 
unsigned long long s0(unsigned long long x) { 
    return rotr(x, 1)^rotr(x, 8)^(x >> 7); 
} 
unsigned long long s1(unsigned long long x) { 
    return rotr(x, 19)^rotr(x, 61)^(x >> 6); 
} 
unsigned long long S0(unsigned long long x) { 
    return rotr(x, 28)^rotr(x, 34)^rotr(x, 39); 
} 
unsigned long long S1(unsigned long long x) { 
    return rotr(x, 14)^rotr(x, 18)^rotr(x, 41); 
} 

Wenn es hilft, ich bin mit Visual Studio 2015. Ich habe versucht, mit dem integrierten 64-bit cl.exe Compiler, und während es mir einen anderen Hash gibt, ist es immer noch nicht das Ziel. Was mache ich hier falsch?

+3

'% (lang lang) (pow (2, 64));' das ist ein Fehler hier. Ich nehme an, dass "unsigned long long int" 64-bit ist, also können Sie diesen Teil entfernen. Verwenden Sie statt 'unsigned long long' 'uint64_t'. – geza

+0

Warum ist diese massive Datentabelle in einer Header-Datei? –

+0

Was ist die erwartete Ausgabe? –

Antwort

1

Es gibt zwei Fehler in dieser Implementierung:

  1. In rotr, sollten Sie 64 - n stattdessen haben von 32 - n
  2. Sie sollten alle % (long long)(pow(2, 64)); entfernen. Wenn Sie uint64_t anstelle von unsigned long long verwendet haben, wurden diese nicht benötigt. Und sie verursachen hier Fehler, weil long long normalerweise 64-bit ist, und es kann die Nummer 2^64 nicht speichern. Verwenden Sie uint64_t "automatisch" verwendet Modulo 2^64.

Und es ist fraglich, alle diese Funktionsdefinitionen und Daten in die Header-Datei zu setzen. Sie sollten mindestens inline für Funktionsdefinitionen verwenden. Aber Sie sollten sie besser in die .cpp verschieben.

+0

Die Datentabelle befindet sich in der Header-Datei, da mein Lehrer sie dort haben möchte. Ich werde es versuchen, wenn ich nach Hause komme. – cerrulean

+0

Ich frage mich, ob er jemals nach Hause gekommen ist? –

Verwandte Themen