6

I'm doing Elgamal Signature Scheme and I need to use the decimal hash value from the message to compute S for signature generation. An example of the hexadecimal hash is:

820dbb4256a4287557ade2f729d279f1

As you can see above, the hash value is a 32-digits hexadecimal number. I need to transform the string above to decimal integer and use it for calculation later.

    string hash = md5(message);
    cout << hash << endl;
    NTL::ZZ msgHash = strtol(hash.c_str(), NULL, 16);
    cout << msgHash << endl;

There are no integer large enough to contain the value of 32 byte hexadecimal hash, and so I tried big integer from NTL library but it didn't work out because you cannot assign the long integer returned from strtol function (And I think the decimal hash value is way longer than long integer range limit) to NTL::ZZ type. Is there any good solution to this?

I'm doing this with visual C++ in Visual Studio 2013.

Wei-jye
  • 412
  • 1
  • 6
  • 23
  • "32-bit hexa hash" sounds like a 32-bit value? Is that wrong? If yes, then please specify the range (or maximum value) of this "creature" (perhaps an `unsigned long long` would be sufficient). – barak manos Jun 03 '14 at 20:53
  • Second point - if you expect `strtol` to extract the integer value from your `hash` string, then this value most certainly fits into an integer... so you probably need to explain the "no integer large enough to contain the value of 32-bit hexa hash" statement. – barak manos Jun 03 '14 at 20:58
  • 2
    If you're doing anything cryptographic and sensitive, **DO NOT** use MD5. It's flawed. You should, at the very least, be using SHA256. In any case, what use is an integer representation of this hash value? – tadman Jun 03 '14 at 21:25
  • @barak MD5 is 128 bits, which is 16 bytes, or 32 bytes as hex characters. The largest type in VS is 64 bits. – Alan Stokes Jun 03 '14 at 21:38
  • 2
    You want the hash *bytes*. Storing them in a platform-native integer type simply isn't going to happen (unless you're on a beast of a platform, and judging by the looks of it (Windows...errm) you're not. The NTL::ZZ class supports left-shift, so what is stopping you from enumerating the string, pulling two chars to assembly an octet, then shift8+add the value. The only tricky part of that algorithm is detecting the hash string length as odd, and if so, pull *one* char for the first iteration (lead octet has only 4 significant bits) then business as usual for the rest of the string. – WhozCraig Jun 03 '14 at 21:56
  • @barak_manos Just added a sample of the hexadecimal hash - "820dbb4256a4287557ade2f729d279f1". So when you convert that string type hexadecimal into integer type decimal, the result should be 172870937377668790778780175506882066929 – Wei-jye Jun 04 '14 at 04:30

1 Answers1

1

The result of MD5 is an octet string (or byte array). The hexadecimal value should just be used to represent the binary value. You need to convert your hexadecimal string back to bytes. This is performed by a hexadecimal decoder found in oodles of libraries.

Then it is required to convert the byte array back to a multi-precision integer. For this you need a libary. Within crypto (which is often based on group theory) it probably makes sense to interpret the bytes as an unsigned, big endian (MSB first) encoded integer.

If it is required to perform any additional cryptography-related calculations then it is a good idea to use a cryptographic library like OpenSSL (C), Crypto++ or Bothan (C++). These libraries already contain methods of handling large (unsigned) numbers and generally hexadecimal codecs as well.

Community
  • 1
  • 1
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263