BN_BN2BIN(3ossl)

πŸ’– BN_BN2BIN πŸ’–

okay bestie, welcome to the BN_BN2BIN page of the OpenSSL manual (that's section 3ossl if you're keeping track πŸ“š). this is the one where all the BIGNUM format conversion girlies live β€” big-endian, little-endian, native, hex, dec, and the MPI situation. grab a snack, we're going through every single one ✨


🌸 NAME 🌸

BN_bn2binpad, BN_signed_bn2bin, BN_bn2bin, BN_bin2bn, BN_signed_bin2bn, BN_bn2lebinpad, BN_signed_bn2lebin, BN_lebin2bn, BN_signed_lebin2bn, BN_bn2nativepad, BN_signed_bn2native, BN_native2bn, BN_signed_native2bn, BN_bn2hex, BN_bn2dec, BN_hex2bn, BN_dec2bn, BN_print, BN_print_fp, BN_bn2mpi, BN_mpi2bn β€” format conversions πŸ’…


✨ SYNOPSIS ✨

#include <openssl/bn.h>

int BN_bn2bin(const BIGNUM *a, unsigned char *to);
int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
int BN_signed_bn2bin(const BIGNUM *a, unsigned char *to, int tolen);
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
BIGNUM *BN_signed_bin2bn(const unsigned char *s, int len, BIGNUM *ret);

int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
int BN_signed_bn2lebin(const BIGNUM *a, unsigned char *to, int tolen);
BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
BIGNUM *BN_signed_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);

int BN_bn2nativepad(const BIGNUM *a, unsigned char *to, int tolen);
int BN_signed_bn2native(const BIGNUM *a, unsigned char *to, int tolen);
BIGNUM *BN_native2bn(const unsigned char *s, int len, BIGNUM *ret);
BIGNUM *BN_signed_native2bn(const unsigned char *s, int len, BIGNUM *ret);

char *BN_bn2hex(const BIGNUM *a);
char *BN_bn2dec(const BIGNUM *a);
int BN_hex2bn(BIGNUM **a, const char *str);
int BN_dec2bn(BIGNUM **a, const char *str);

int BN_print(BIO *fp, const BIGNUM *a);
int BN_print_fp(FILE *fp, const BIGNUM *a);

int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
BIGNUM *BN_mpi2bn(unsigned char *s, int len, BIGNUM *ret);

πŸ¦‹ DESCRIPTION πŸ¦‹

🌈 big-endian, no padding

BN_bn2bin() takes the absolute value of a, converts it to big-endian form, and drops it at to. to has to point at BN_num_bytes(a) bytes of memory β€” no more, no less, she's precise like that. and btw a and to MUST NOT be NULL. like, at all. πŸ™ˆ

πŸŽ€ big-endian, but padded

BN_bn2binpad() also converts the absolute value of a into big-endian form and stores it at to. this time tolen tells you how long the output buffer to is. the result gets padded with zeros if it needs to be. but if tolen is less than BN_num_bytes(a), that's an error, bestie. no room, no entry 🚫

⭐ big-endian, but SIGNED

BN_signed_bn2bin() converts the value of a into big-endian signed 2's complement form and stores it at to. tolen is the length of the output buffer to. if necessary the result is sign extended β€” padded with 0x00 for positive numbers or with 0xff for negative numbers. if tolen is smaller than the necessary size (which may be "<BN_num_bytes(a) + 1">), you get an error. it's giving tight fit πŸ’€

🧚 bytes β†’ BIGNUM

BN_bin2bn() takes the positive integer in big-endian form, of length len, sitting at s, and turns it into a BIGNUM, placing it in ret. if ret is NULL, a fresh new BIGNUM gets created for you 🫢 and s MUST NOT be NULL.

BN_signed_bin2bn() does the same thing but for the integer in big-endian signed 2's complement form of length len at s, turning it into a BIGNUM and placing it in ret. if ret is NULL, again, new BIGNUM, no cap.

πŸ’œ little-endian crew

BN_bn2lebinpad(), BN_signed_bn2lebin() and BN_lebin2bn() are identical to BN_bn2binpad(), BN_signed_bn2bin() and BN_bin2bn() respectively β€” except the buffer is in little-endian format. that's the whole plot twist, that's it, she ate πŸ’…

🌸 native crew

BN_bn2nativepad(), BN_signed_bn2native() and BN_native2bn() are also identical to BN_bn2binpad(), BN_signed_bn2bin() and BN_bin2bn() β€” except the buffer is in native format. translation: most significant byte first on big-endian platforms, and least significant byte first on little-endian platforms. she adapts to her environment, main character energy fr fr πŸ‘‘

πŸ“ hex and dec, string edition

BN_bn2hex() and BN_bn2dec() return printable strings containing the hexadecimal and decimal encoding of a, respectively. for negative numbers, the string is prefaced with a leading '-'. and listen β€” the string must be freed later using OPENSSL_free(). do not forget. i will know. 😭

BN_hex2bn() takes as many characters as possible from the string str, including the leading character '-' (which means negative, obviously), to form a valid hexadecimal number representation, converts them to a BIGNUM, and stores it in **a. if *a is NULL, a new BIGNUM is created. if a is NULL, it only computes the length of the valid representation. and a "negative zero" is converted to zero β€” yes, that's a thing, and she said not today. BN_dec2bn() is the same deal but with the decimal system.

πŸŽ€ printing to BIO / FILE

BN_print() and BN_print_fp() write the hexadecimal encoding of a β€” with a leading '-' for negative numbers β€” to the BIO or FILE fp. cute, formatted, done ✨

πŸ‘‘ the MPI format

BN_bn2mpi() and BN_mpi2bn() convert BIGNUMs from and to a format that consists of:

  1. the number's length in bytes, represented as a 4-byte big-endian number, and
  2. the number itself in big-endian format, where the most significant bit signals a negative number β€” meaning the representation of numbers with the MSB set is prefixed with a null byte.

BN_bn2mpi() stores the representation of a at to, where to must be large enough to hold the result. you can figure out the size by calling BN_bn2mpi(a, NULL). yes, the NULL trick, she's iconic for that.

BN_mpi2bn() converts the len bytes long representation at s to a BIGNUM and stores it at ret, or in a newly allocated BIGNUM if ret is NULL.


πŸ’€ RETURN VALUES πŸ’€

  • BN_bn2bin() returns the length of the big-endian number placed at to. BN_bin2bn() returns the BIGNUM, or NULL on error.
  • BN_bn2binpad(), BN_signed_bn2bin(), BN_bn2lebinpad(), BN_signed_bn2lebin(), BN_bn2nativepad(), and and_signed BN_bn2native() return the number of bytes written, or -1 if the supplied buffer is too small. (yes, that last one is written exactly like that in the manual, and honestly, same energy as autocorrect at 2am πŸ™ˆ)
  • BN_bn2hex() and BN_bn2dec() return a NUL-terminated string, or NULL on error. BN_hex2bn() and BN_dec2bn() return the number of characters used in parsing, or 0 on error β€” and in that error case, no new BIGNUM will be created.
  • BN_print_fp() and BN_print() return 1 on success, 0 on write errors.
  • BN_bn2mpi() returns the length of the representation. BN_mpi2bn() returns the BIGNUM, and NULL on error.
and if you need the error codes, bestie, you get them with ERR_get_error(3) πŸ’–

🌈 SEE ALSO 🌈

ERR_get_error(3), BN_zero(3), ASN1_INTEGER_to_BN(3), BN_num_bytes(3)


πŸ¦‹ HISTORY πŸ¦‹

the signed girlies β€” BN_signed_bin2bn(), BN_signed_bn2bin(), BN_signed_lebin2bn(), BN_signed_bn2lebin(), BN_signed_native2bn(), BN_signed_bn2native() β€” were added in OpenSSL 3.2. new-ish, but already thriving ✨


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>.


okay that's the whole page, you're officially educated πŸŽ“ this was OpenSSL 3.5.9, dated 2026-09-29, and that's the BN_BN2BIN(3ossl) tea. go forth and convert your formats responsibly, ily, bye πŸ’–πŸŒΈπŸ¦‹

πŸ“¦ where this page comes from