BN_ADD(3ossl)
๐ 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()โ addsaandband drops the result inr(r=a+b). and yes,rcan literally be the sameBIGNUMasaorb, in-place slay. ๐ซถBN_sub()โ subtractsbfroma, result goes inr(r=a-b). and again,rmay be the sameBIGNUMasaorb. iconic.BN_mul()โ multipliesaandb, plops the result inr(r=a*b).rmay be the sameBIGNUMasaorb. small note tho: if you're multiplying by powers of 2, useBN_lshift(3)instead, iykyk. ๐BN_sqr()โ squaresaand puts it inr(r=a^2).randamay be the sameBIGNUM. and listen, this is literally faster thanBN_mul(r,a,a), so use it. โกBN_div()โ dividesabyd, quotient goes indv, remainder goes inrem(dv=a/d, rem=a%d). either ofdvandremmay beNULL, and then that value just doesn't get returned, no drama. rounding is towards zero, so ifais negative, the remainder will be zero or negative. ๐ and for division by powers of 2, useBN_rshift(3).BN_mod()โ this is basicallyBN_div()withdvset toNULL. periodt.BN_nnmod()โ reducesamodulomand puts the nonnegative remainder inr. ๐BN_mod_add()โ addsatobmodulomand puts the nonnegative result inr.BN_mod_sub()โ subtractsbfromamodulomand puts the nonnegative result inr.BN_mod_mul()โ multipliesabyband finds the nonnegative remainder with respect to modulusm(r=(a*b) mod m).rmay be the sameBIGNUMasaorb. and if you're doing repeated computations with the same modulus and want the more efficient algorithms, go look atBN_mod_mul_montgomery(3)andBN_mod_mul_reciprocal(3). ๐BN_mod_sqr()โ takes the square ofamodulomand places the result inr.BN_mod_sqrt()โ returns the modular square root ofasuch thatin^2 = a (mod p). the moduluspmust 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 intoin, which can beNULL, and in that case the result is newly allocated.BN_exp()โ raisesato thep-th power and puts the result inr(r=a^p). this is faster than repeatedly applyingBN_mul(), we love efficiency. ๐ฅBN_mod_exp()โ computesato thep-th power modulom(r=a^p % m). uses less time and space thanBN_exp(). ๐ฆ do not call this function whenmis even and any of the parameters have theBN_FLG_CONSTTIMEflag set โ that's a hard no, fr fr.BN_gcd()โ computes the greatest common divisor ofaandband places the result inr.rmay be the sameBIGNUMasaorb. ๐
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 ๐
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
- freebsd 15.1: base 15.1
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms