Math using OpenSSL BIGNUMs: How to calculate multiplicative inverse?
-
13-07-2021 - |
Question
I'm having some issues with OpenSSL BIGNUMs. I'm trying to implement a basic ElGamal protocol. The problem i'm having is that some of these calculations are not returning the values i'm expecting! This is mostly obvious when i try to calculate a multiplicative inverse.
For example:
static void roughExample() {
BIGNUM *u1 = BN_new();
BIGNUM *u2 = BN_new();
BIGNUM *one = BN_new();
BN_one(one);
BIGNUM *negOne = BN_new();
BN_zero(negOne);
BN_sub(negOne, negOne, one); // So negOne should = -1 and it does
BN_print_fp(stdout, negOne); //shows -1 here
BN_rand_range(u1, q); // q = large prime, point being that u1 = random large num
BN_print_fp(stdout, u1);
BN_exp(u2, u1, negOne, ctx);
BN_print_fp(stdout, u2); // in the output, u1 = u2.
}
The output above comes out as: -1, [large prime], [exact same large prime].
So clearly BN_exp isn't doing what i'm expecting it to. In this case I suppose i can just use BN_div to do 1/x, but i'm wondering if there is a larger picture that i'm missing. I am using doing lots of calculations like this and i won't always be able to visually verify that the value has changed like i expected.
Can anyone help? Thanks in advance!
Edit: I tried using 1/x, and it produces a value of 0... :/
Solution
You need a BN_mod_inverse
function. Other functions don't provide such algorithm.
You can also perform exponentiation to (q-2) modulo q, if q is prime. And you will get inverse field member due to Fermat's little theorem.