BN_ADD(3SSL)
π BN_ADD β the OpenSSL math page, bestie edition π
okay so. this is a page from the OpenSSL manual (section 3SSL, so like, a library function page), and it's literally the whole girl-math starter pack: adding, subtracting, multiplying, dividing, modular everything, and gcd. BIGNUMs are the big-number baddies behind all your crypto, and these functions are how you do arithmetic on them. let's get into it π
β¨ 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. yes, all of them. it's a whole friend group π«Ά
β¨ 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 lemme go one by one, no skips, we're doing the full roster π
BN_add()β addsaandband drops the result inr("r=a+b"). and get this:ris allowed to be the exact same BIGNUM asaorb. iconic, low-effort in-place vibes.BN_sub()β subtractsbfroma, result lands inr("r=a-b"). same deal:rcan be the same BIGNUM asaorb.BN_mul()β multipliesaandb, result inr("r=a*b").rmay be the same BIGNUM asaorb. but listen, if you're multiplying by powers of 2, don't do this, useBN_lshift(3)instead okay? it's better for that.BN_sqr()β squaresa, result inr("r=a^2").randacan be the same BIGNUM. and it's faster thanBN_mul(r,a,a), so if you were about to do that, bestie, no. use this one.BN_div()β dividesabyd, puts the quotient indvand the remainder inrem("dv=a/d, rem=a%d"). either ofdvandremcan beNULL, and in that case that value just isn't returned (no drama, it's fine). β οΈ the result is rounded towards zero, so ifais negative, the remainder will be zero or negative. and for dividing by powers of 2, useBN_rshift(3)instead.BN_mod()β it's literallyBN_div()but withdvset toNULL. that's it. that's the function.BN_nnmod()β reducesamodulomand puts the nonnegative remainder inr. the double-n is doing the work here, nn = nonnegative, iykyk.BN_mod_add()β addsatobmodulom, and the nonnegative result goes inr.BN_mod_sub()β subtractsbfromamodulom, nonnegative result inr.BN_mod_mul()β multipliesabyband finds the nonnegative remainder with respect to modulusm("r=(a*b) mod m").rcan be the same BIGNUM asaorb. and if you're doing repeated computations with the same modulus, there are more efficient algorithms waiting for you inBN_mod_mul_montgomery(3)andBN_mod_mul_reciprocal(3)β go look, it's giving optimization β¨BN_mod_sqr()β squaresamodulom, result inr.BN_mod_sqrt()β returns the modular square root ofasuch that"in^2 = a (mod p)". β οΈ the moduluspmust be a prime, otherwise you get an error or an incorrect"result"(yes those scare quotes are doing heavy lifting). the result gets stored intoin, which can beNULLβ and in that case the result is newly allocated for you. cute.BN_exp()β raisesato thep-th power, result inr("r=a^p"). this is faster than repeatedly callingBN_mul(), so stop looping, babe.BN_mod_exp()β computesato thep-th power modulom("r=a^p % m"). it uses less time and space thanBN_exp(). π¨ but do not call this function whenmis even and any of the parameters have theBN_FLG_CONSTTIMEflag set. that one's a hard no.BN_gcd()β computes the greatest common divisor ofaandb, result inr.rmay be the same BIGNUM asaorb. love that for us.
now, the house rules for all of them π:
for every function that takes a ctx parameter, that ctx has to be a previously allocated BN_CTX used for temporary variables β peep BN_CTX_new(3). and unless a specific function's own documentation says otherwise, ctx must not be NULL.
and unless noted otherwise, the result BIGNUM must be different from the arguments. (some of them allow aliasing, as noted above β but don't just assume, mkay?)
β¨ NOTES β¨
for modular operations like BN_nnmod() or BN_mod_exp(), it is an error to use the same BIGNUM object for the modulus as for the output. π like, do not. that's not a vibe check you want to fail.
β¨ RETURN VALUES β¨
BN_mod_sqrt() returns the result (which may be incorrect if p is not a prime, and we did warn you), or NULL.
for all the remaining functions: 1 for success, 0 on error. and you should always check that return value, no exceptions, like this:
if (!BN_add(r,a,b)) goto err;
the error codes can be obtained by ERR_get_error(3). π«Ά
β¨ SEE ALSO β¨
ERR_get_error(3), BN_CTX_new(3), BN_add_word(3), BN_set_bit(3)
β¨ COPYRIGHT β¨
Copyright 2000-2026 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 whole page, bestie π this was OpenSSL 4.0.3, dated 2026-09-29, and yeah the page id is BN_ADD(3SSL). slay, go do some big-number math responsibly. πβ¨π
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms