Home > OS >  c programming - working with BIGNUM in openssl
c programming - working with BIGNUM in openssl

Time:01-21

i am trying to add two big numbers using openssl library in c but i really don't know how to work with it.

The documentation of openssl - BN_add() is here https://www.openssl.org/docs/man3.0/man3/BN_add.html

//#include <openssl/bn.h>

//BN_add() adds a and b and places the result in r (r=a b).
//r may be the same BIGNUM as a or b.

int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);

what is a & b expecting from me? an array of bytes? a string?

Anyone who worked with adding bignumbers in openssl and have a simple example?

CodePudding user response:

To use BN_add you need three BIGNUM artifacts: the two operands you're trying to add and a place to store the result. The source of the operands can vary, depending on the nature of the source data and possible conversions therein. The result should be acquired with BN_new.

A trivial example using two decimal digit strings appears below:

#include <stdio.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>

int main()
{
    const char n1[] = "12345678912345789123456789123456789";
    const char n2[] = "12345678912345789123456789123456789";

    BIGNUM *bn1 = NULL;
    BN_dec2bn(&bn1, n1);

    BIGNUM *bn2 = NULL;
    BN_dec2bn(&bn2, n2);

    BIGNUM *bn3 = BN_new();
    BN_add(bn3, bn1, bn2);

    char *n3 = BN_bn2dec(bn3);
    printf("%s\n%s\n%s\n", n1, n2, n3);
    OPENSSL_free(n3); // don't forget to free this.
    
    BN_free(bn1);
    BN_free(bn2);
    BN_free(bn3);

    return 0;
}

Output

12345678912345789123456789123456789
12345678912345789123456789123456789
24691357824691578246913578246913578

Note that we make sure to free everything we acquire, and that includes the conversion to decimal char string of the result, which per BN_bn2dec documentation, must be freed with OPENSSL_free.

This isn't the only way to do this, and different methodologies depend highly on the source data. For example, we can modify the above program to convert two 256 bit numbers from big-endian byte octets into BIGNUM. To do that, we may use BN_bin2bn. The rest of the code, however, would look similar (save for some additional conversion buffers that must be freed).

#include <stdio.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>

int main()
{
    unsigned char n1[32];
    unsigned char n2[32];

    RAND_bytes(n1, sizeof n1);
    RAND_bytes(n2, sizeof n2);

    BIGNUM *bn1 = BN_bin2bn(n1, sizeof n1, NULL);
    BIGNUM *bn2 = BN_bin2bn(n2, sizeof n2, NULL);

    BIGNUM *bn3 = BN_new();
    BN_add(bn3, bn1, bn2);

    char *s1 = BN_bn2dec(bn1);
    char *s2 = BN_bn2dec(bn2);
    char *s3 = BN_bn2dec(bn3);
    printf("%s\n%s\n%s\n", s1, s2, s3);
    OPENSSL_free(s1);
    OPENSSL_free(s2);
    OPENSSL_free(s3);
    
    BN_free(bn1);
    BN_free(bn2);
    BN_free(bn3);

    return 0;
}

Output (varies, obviously)

12848991999079618356122471791635779303297173135339588614513279277444395635360
47516096440756489210553139954635811049213722081352926332729551875133172387567
60365088439836107566675611746271590352510895216692514947242831152577568022927
  •  Tags:  
  • Related