0

In C++, I am trying to convert an array of int representing a big integer to a BIGNUM using the OpenSSL library.

It's OK with an string containing the hexadecimal encoding of the big number, but I can't find how to do it with an array.

#include <openssl/bn.h>

int main()
{
    uint32_t hash[4] = { 0x3506fa7d, 0x6bb2dbe9, 0x9041d8e5, 0x6ea31f6b };
    const char p_hash[] = "3506fa7d6bb2dbe99041d8e56ea31f6b";

    BIGNUM *bn_result1 = BN_new();
    BN_hex2bn(&bn_result1, p_hash);

    std::cout << "Big number as Dec: " << BN_bn2dec(bn_result1) << std::endl;
    std::cout << "Big number as Hex: " << BN_bn2hex(bn_result1) << std::endl;

    // How to convert hash[4] to BIGNUM bn_result2?
}
LeMoussel
  • 5,290
  • 12
  • 69
  • 122
  • 1
    If your raw number isn't in one of the formats described [here](https://www.openssl.org/docs/man1.0.2/man3/BN_bn2bin.html), convert it to one, or write your own routine to build a bignum from what you have using the addition, shift, etc. functions. – Shawn Apr 15 '19 at 16:54

1 Answers1

2

Possible solution with htobe32 and BN_bin2bn:

for(i=0; i<4; i++) {
    hash[i] = htobe32(hash[i]); /* BN_bin2bn needs big endian data */
}

BN_bin2bn((const unsigned char *)hash, (4*4), &bn_result2);

If you are sure your host byte order is big endian you could omit the conversion, but doing so you will lose portability.

Edit:

The same applies to the little-endian version BN_lebin2bn if your host byte order is little-endian.

Bodo
  • 9,287
  • 1
  • 13
  • 29
  • Possible to skip `htobe32()` with `BN_lebin2bn()`? – akhan May 15 '21 at 19:37
  • 1
    @akhan Using `htobe32` is portable since it will convert the host byte order to big endian regardless of whether the host uses little endian or big endian. If you are sure that your host uses little endian you could use `BN_lebin2bn`, but this program will be non-portable as it works for little-endian platforms only. Of course you could also write a portable program using `htole32` and `BN_lebin2bn`. – Bodo May 17 '21 at 08:56