Implementation:Duckdb Duckdb Mbedtls Bignum
| Knowledge Sources | |
|---|---|
| Domains | Cryptography, Third_Party |
| Last Updated | 2026-02-07 12:00 GMT |
Overview
The mbedTLS Bignum module provides a multi-precision integer (MPI) library for arbitrary-precision arithmetic, serving as the mathematical foundation for RSA, elliptic curve, and other public-key cryptographic operations.
Description
This module implements arbitrary-precision integer arithmetic using a limb-based representation. The core data structure mbedtls_mpi consists of three fields:
p: Pointer to an array of limbs (mbedtls_mpi_uintvalues, either 32-bit or 64-bit depending on the platform)s: Sign flag (-1 for negative, +1 for non-negative)n: Number of allocated limbs (maximum 65535, bounded byMBEDTLS_MPI_MAX_LIMBS= 10000)
The module is organized across multiple files:
bignum.h/bignum.cpp: High-level MPI API including initialization, comparison, I/O, arithmetic (add, subtract, multiply, divide), modular arithmetic, GCD, modular exponentiation, and primality testing. Operations use theMBEDTLS_MPI_CHKmacro for error propagation with goto-based cleanup.
bignum_core.h/bignum_core.cpp: Low-level core operations on fixed-size unsigned limb arrays. This internal API operates on non-negative integers with a fixed upper bound of 2^n-1 where n is a multiple of the limb size. Functions includembedtls_mpi_core_clz()(count leading zeros),mbedtls_mpi_core_bitlen()(bit length), and endianness conversion. The core module defines fundamental constants:ciL(chars in limb),biL(bits in limb), andbiH(half limb size).
bn_mul.h: Platform-specific multiply-accumulate macros with optimized assembly for IA-32, AMD64, ARM, PowerPC, SPARC, Alpha, MIPS, and other architectures. Also providesMBEDTLS_BYTES_TO_T_UINT_*conversion macros for embedding constants.
The bignum module uses constant-time comparison functions (mbedtls_mpi_lt_mpi_ct) to prevent timing side-channel attacks during sensitive cryptographic operations.
Usage
DuckDB uses the bignum module as the mathematical backbone for:
- RSA operations: All RSA key components (N, E, D, P, Q) are stored as
mbedtls_mpivalues; key generation, encryption, and signing use bignum modular exponentiation - Elliptic curve arithmetic: ECP point coordinates and curve parameters are represented as MPIs
- ASN.1 parsing: Large integer values in DER-encoded certificates and keys are read into
mbedtls_mpistructures - Extension signature verification: The RSA signature verification process relies on bignum modular arithmetic
Code Reference
Source Location
- Repository: Duckdb_Duckdb
- Files:
- third_party/mbedtls/include/mbedtls/bignum.h -- Big number API header (1084 lines)
- third_party/mbedtls/library/bignum.cpp -- Big number arithmetic (2487 lines)
- third_party/mbedtls/library/bignum_core.cpp -- Core bignum operations (1021 lines)
- third_party/mbedtls/library/bignum_core.h -- Core bignum header (825 lines)
- third_party/mbedtls/library/bn_mul.h -- Bignum multiplication macros (1094 lines)
Signature
// MPI context lifecycle
void mbedtls_mpi_init(mbedtls_mpi *X);
void mbedtls_mpi_free(mbedtls_mpi *X);
// Memory management
int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs);
int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs);
int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y);
// Constant-time comparison
int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
const mbedtls_mpi *Y,
unsigned *ret);
// Core operations (internal API)
size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a);
size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs);
Import
#include "mbedtls/bignum.h"
// Internal core operations:
#include "bignum_core.h"
#include "bn_mul.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| X | mbedtls_mpi * |
Yes | MPI context to initialize, grow, or use as destination |
| Y | const mbedtls_mpi * |
For copy/compare | Source MPI for copy or comparison operand |
| nblimbs | size_t |
For grow/shrink | Target number of limbs (must be >= 1) |
| A | const mbedtls_mpi_uint * |
Core ops | Pointer to limb array for core operations |
| A_limbs | size_t |
Core ops | Number of limbs in the array |
Outputs
| Name | Type | Description |
|---|---|---|
| return value | int |
0 on success; error codes include MBEDTLS_ERR_MPI_ALLOC_FAILED (-0x0010), MBEDTLS_ERR_MPI_BAD_INPUT_DATA (-0x0004), MBEDTLS_ERR_MPI_DIVISION_BY_ZERO (-0x000C)
|
| ret | unsigned * |
Comparison result for mbedtls_mpi_lt_mpi_ct: 1 if X < Y, 0 otherwise
|
| (size_t) | size_t |
Bit length or leading zero count from core operations |
Usage Examples
// Basic MPI arithmetic
mbedtls_mpi A, B, C;
mbedtls_mpi_init(&A);
mbedtls_mpi_init(&B);
mbedtls_mpi_init(&C);
// Read from string (base 16)
mbedtls_mpi_read_string(&A, 16, "DEADBEEF");
mbedtls_mpi_read_string(&B, 16, "01");
// Compute C = A + B
mbedtls_mpi_add_mpi(&C, &A, &B);
// Constant-time comparison (side-channel safe)
unsigned is_less;
mbedtls_mpi_lt_mpi_ct(&A, &B, &is_less);
mbedtls_mpi_free(&A);
mbedtls_mpi_free(&B);
mbedtls_mpi_free(&C);