BN_ADD(3ossl)

๐Ÿ“ฆ
version 15.1 ยท 3 versions
, in freebsd 15.1

๐Ÿ’… BN_ADD(3ossl) โ€” the OpenSSL bignum math page, bestie edition โœจ

okay so this is the BN_ADD(3ossl) page from OpenSSL, and it's literally the whole glow-up arc of big-number arithmetic. no cap, this is the page that teaches you how to add, subtract, multiply, divide, mod, and exponentiate BIGNUMs like a main character. ๐ŸŽ€


โœจ NAME โœจ

BN_add, BN_sub, BN_mul, BN_sqr, BN_div, BN_mod, BN_nnmod, BN_mod_add, BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_mod_sqrt, BN_exp, BN_mod_exp, BN_gcd โ€” arithmetic operations on BIGNUMs ๐Ÿงฎ๐Ÿ‘‘

๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <openssl/bn.h>

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

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

int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);

int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);

int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a, const BIGNUM *d,
           BN_CTX *ctx);

int BN_mod(BIGNUM *rem, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);

int BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);

int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);

int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);

int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
               BN_CTX *ctx);

int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);

BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);

int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);

int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
               const BIGNUM *m, BN_CTX *ctx);

int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so buckle up, bestie, we're going function by function and every single one of them ate. โœจ

  • BN_add() โ€” adds a and b and drops the result in r (r=a+b). and yes, r can literally be the same BIGNUM as a or b, in-place slay. ๐Ÿซถ
  • BN_sub() โ€” subtracts b from a, result goes in r (r=a-b). and again, r may be the same BIGNUM as a or b. iconic.
  • BN_mul() โ€” multiplies a and b, plops the result in r (r=a*b). r may be the same BIGNUM as a or b. small note tho: if you're multiplying by powers of 2, use BN_lshift(3) instead, iykyk. ๐Ÿ’…
  • BN_sqr() โ€” squares a and puts it in r (r=a^2). r and a may be the same BIGNUM. and listen, this is literally faster than BN_mul(r,a,a), so use it. โšก
  • BN_div() โ€” divides a by d, quotient goes in dv, remainder goes in rem (dv=a/d, rem=a%d). either of dv and rem may be NULL, and then that value just doesn't get returned, no drama. rounding is towards zero, so if a is negative, the remainder will be zero or negative. ๐ŸŒ€ and for division by powers of 2, use BN_rshift(3).
  • BN_mod() โ€” this is basically BN_div() with dv set to NULL. periodt.
  • BN_nnmod() โ€” reduces a modulo m and puts the nonnegative remainder in r. ๐ŸŽ€
  • BN_mod_add() โ€” adds a to b modulo m and puts the nonnegative result in r.
  • BN_mod_sub() โ€” subtracts b from a modulo m and puts the nonnegative result in r.
  • BN_mod_mul() โ€” multiplies a by b and finds the nonnegative remainder with respect to modulus m (r=(a*b) mod m). r may be the same BIGNUM as a or b. and if you're doing repeated computations with the same modulus and want the more efficient algorithms, go look at BN_mod_mul_montgomery(3) and BN_mod_mul_reciprocal(3). ๐Ÿ‘‘
  • BN_mod_sqr() โ€” takes the square of a modulo m and places the result in r.
  • BN_mod_sqrt() โ€” returns the modular square root of a such that in^2 = a (mod p). the modulus p must be a prime, otherwise you get an error or an incorrect "result" โ€” like, it will hand you something and it will be wrong, so be careful. ๐Ÿ˜ญ the result is stored into in, which can be NULL, and in that case the result is newly allocated.
  • BN_exp() โ€” raises a to the p-th power and puts the result in r (r=a^p). this is faster than repeatedly applying BN_mul(), we love efficiency. ๐Ÿ”ฅ
  • BN_mod_exp() โ€” computes a to the p-th power modulo m (r=a^p % m). uses less time and space than BN_exp(). ๐Ÿฆ‹ do not call this function when m is even and any of the parameters have the BN_FLG_CONSTTIME flag set โ€” that's a hard no, fr fr.
  • BN_gcd() โ€” computes the greatest common divisor of a and b and places the result in r. r may be the same BIGNUM as a or b. ๐ŸŒˆ

and for all of these functions, ctx is a previously allocated BN_CTX used for temporary variables; see BN_CTX_new(3). ๐Ÿ’œ

unless noted otherwise, the result BIGNUM must be different from the arguments. like, that's the rule, don't fight it.

๐Ÿฆ‹ NOTES ๐Ÿฆ‹

for modular operations such as BN_nnmod() or BN_mod_exp(), it is an error to use the same BIGNUM object for the modulus as for the output. ๐Ÿšจ same object = no no, that's undefined-behaviour-flavored chaos and we don't do that here.

โญ RETURN VALUES โญ

BN_mod_sqrt() returns the result โ€” which, reminder, may be incorrect if p is not a prime โ€” or NULL. ๐Ÿ™ˆ

for all the remaining functions, 1 means success and 0 means error. always check the return value, bestie, like:

if (!BN_add(r,a,b)) goto err;

and the error codes can be obtained with ERR_get_error(3). ๐Ÿ’€

๐ŸŒธ SEE ALSO ๐ŸŒธ

ERR_get_error(3), BN_CTX_new(3), BN_add_word(3), BN_set_bit(3)

Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


and that's the page, bestie ๐Ÿ’…โœจ this was OpenSSL 3.5.6, dated 2026-04-07 โ€” BN_ADD(3ossl), signing off ๐Ÿซถ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from