How not to do cryptography

I am trying write a simple program to encode something using SHA-3 and the crypto++ libs. I have not found a tutorial on this. Rather I have look at some other post and tutorials which seem fairly similar and looking at the header file. So far I have this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <crypto++/sha3.h>
#include <crypto++/filters.h>
#include <crypto++/hex.h>
#include <iostream>
#include <string>
using namespace std;
int main(){
    CryptoPP::SHA3_512 hash;
    cout << hash.AlgorithmName() << " Test." <<endl;  
    std::string in = "Test encryption input";
    byte out[hash.DigestSize()];
    hash.Restart();
    unsigned char buffer[in.size()];
    memcpy( buffer, in.data(), in.size());
    hash.Update( buffer, in.size() );
    hash.TruncatedFinal(out, hash.DigestSize());
    cout <<in<<endl;
    cout <<out<<endl;
}


Basically the output is complete garbage. I think there is a memory leak as well because the last time I ran the program it screwed up the terminal. Technically, I don't even know if I am issuing the correct commands. I wasn't able to find any documentation and just went off of what was in the header.
I think the problem has to do with the conversion of types for the input. Using memcpy was the only way I could make it work. a lot of posts advocate using .c_str() however this produces a signed char and no amount of type casting which I applied was able to rectify the problem.

Also, not that it matters, but everyone else seem to use the string member function .length(), This doesn't work for me. However .size() works fine. What is the difference and why would that happen.
You should probably allocate memory here:
byte out[hash.DigestSize()];

and here:
unsigned char buffer[in.size()];

Note in c++, char is 1 byte, so unless you have another byte class somewhere, you should be using char here

Not sure why string::length() is returning a different value from string::size(). According to the documentation, they should return the same values,
Both string::size and string::length are synonyms and return the exact same value.
Last edited on
I tried this.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <crypto++/sha3.h>
#include <crypto++/filters.h>
#include <crypto++/hex.h>
#include <iostream>
#include <string>
using namespace std;
int main(){
    CryptoPP::SHA3_512 hash;
    cout << hash.AlgorithmName() << " Test." <<endl;  
    std::string in = "Test encryption input";
    byte * buffer = (unsigned char*) malloc( in.size() );
    byte * out = (unsigned char*) malloc( hash.DigestSize() );
    hash.Restart();
    memcpy( buffer, in.data(), in.size());
    hash.Update( buffer, in.size() );
    hash.TruncatedFinal(out, hash.DigestSize());
    cout <<in<<endl;
    cout <<out<<endl;
}


same results. including the screwed up screen.
Your original code works fine for me. The problem is that you are outputting binary data to the screen.

Try this:
1
2
3
4
    for(uint i=0; i<hash.DigestSize(); ++i) {
        cout << setw(2) << setfill('0') << hex << (int)out[i];
    }
    cout  <<endl;


Hashing "The quick brown fox jumps over the lazy dog" outputs the following:
d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609
which exactly matches the digest in "TestVectors/sha3.txt" of the library package.
Since you are only hashing a single string you can use CalculateDigest() or CalculateTruncatedDigest().
1
2
3
4
5
6
7
8
9
10
11
12
13
int main(){
    CryptoPP::SHA3_512 hash;
    
    cout << hash.AlgorithmName() << " Test." << endl;

    string in = "The quick brown fox jumps over the lazy dog";
    vector<byte> out(hash.DigestSize());
   
    hash.CalculateTruncatedDigest(&out[0], hash.DigestSize(), reinterpret_cast<byte*>(&in[0]), in.size());

    cout << in << endl;
    cout << out << endl;
}


Also, there is documentation http://www.cryptopp.com/docs/ref/index.html
Topic archived. No new replies allowed.