|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
2048-bit big-integer arithmetic for DH-group14 and RSA-2048. More...
#include "protocore_config.h"#include "server/mmgr/secure.h"#include <stddef.h>#include <stdint.h>#include <string.h>Go to the source code of this file.
Classes | |
| struct | pc_bignum |
| A 2048-bit unsigned integer stored as 64 little-endian 32-bit limbs. More... | |
Macros | |
| #define | PC_BN_LIMBS 64 |
| Number of 32-bit limbs in a 2048-bit integer. | |
Functions | |
| void | bn_from_bytes (pc_bignum *out, const uint8_t *bytes, size_t len) |
Read a big-endian byte array of len bytes into a pc_bignum. | |
| void | bn_to_bytes (uint8_t bytes[256], const pc_bignum *in) |
| Write a pc_bignum as a 256-byte big-endian array. | |
| int | bn_cmp (const pc_bignum *a, const pc_bignum *b) |
| Compare two pc_bignum values. | |
| int | bn_is_zero (const pc_bignum *a) |
Return non-zero if a is zero (all limbs zero). | |
| int | bn_cmp_raw (const uint32_t *a, const uint32_t *b, int n) |
| Compute out = base^exp mod group14_p. | |
| void | bn_expmod_group14 (pc_bignum *out, const pc_bignum *base, const pc_bignum *exp) |
| int | bn_dh_validate (const pc_bignum *v) |
| Validate a received DH public value. | |
Variables | |
| const pc_bignum | group14_p |
| The RFC 3526 MODP group-14 prime (2048-bit). | |
| const pc_bignum | group14_g |
| Generator for group-14: g = 2. | |
2048-bit big-integer arithmetic for DH-group14 and RSA-2048.
═══════════════════════════════════════════════════════════════════════════ DESIGN RATIONALE ═══════════════════════════════════════════════════════════════════════════
pc_bignum is a fixed-width 2048-bit integer stored as 64 little-endian 32-bit limbs (d[0] = least significant). Fixed width means:
On Arduino (ESP32), DH uses mbedtls_mpi from ESP-IDF (heap-allocated, variable-length bignum), which has hardware-accelerated multiplication. On native builds, the software Montgomery path is used - correct but slower (~200 ms for a 2048-bit exponentiation on x86 at test time). Since DH happens once per connection and ESP32 uses the HW path in production, the native speed is acceptable for testing.
═══════════════════════════════════════════════════════════════════════════ MONTGOMERY MULTIPLICATION ═══════════════════════════════════════════════════════════════════════════
For DH-group14 the modulus p ends in ...FFFFFFFF FFFFFFFF (little-endian d[0]=0xFFFFFFFF). This gives Montgomery parameter:
p_inv = (-(p mod 2^32))^(-1) mod 2^32 = (-(0xFFFFFFFF))^(-1) mod 2^32 = (0x00000001)^(-1) mod 2^32 = 1
p_inv = 1 simplifies the inner reduction loop: m_i = t[i] * 1 = t[i].
Montgomery product: MonPro(a,b) = a·b·R^-1 mod p where R = 2^2048.
To compute a·b mod p normally:
R² mod p is a precomputed 2048-bit constant (see pc_bignum.cpp).
═══════════════════════════════════════════════════════════════════════════ SCRATCH BUFFER ═══════════════════════════════════════════════════════════════════════════
The Montgomery SOS multiplication needs a 129-word (516-byte) temporary and the expmod three pc_bignum temporaries (768 bytes). bn_expmod_group14() borrows all of them as ONE working set from the secure pool (server/mmgr/secure.h), so the layout is the struct's own field order rather than byte offsets kept in step by hand here.
These temporaries hold DH private-exponent and shared-secret fragments. They are wiped when the borrow is released - by the pool, on every exit path. This module does not perform the wipe and does not need to know that one happens.
═══════════════════════════════════════════════════════════════════════════
Definition in file bignum.h.
| #define PC_BN_LIMBS 64 |
| void bn_from_bytes | ( | pc_bignum * | out, |
| const uint8_t * | bytes, | ||
| size_t | len | ||
| ) |
Read a big-endian byte array of len bytes into a pc_bignum.
If len < 256 the most-significant limbs are zeroed. If len > 256 only the least-significant 256 bytes are read.
| out | Destination bignum. |
| bytes | Big-endian source bytes. |
| len | Number of source bytes (typically 256 for 2048-bit). |
Definition at line 84 of file bignum.cpp.
References pc_bignum::d.
Referenced by ssh_kexdh_handle().
| void bn_to_bytes | ( | uint8_t | bytes[256], |
| const pc_bignum * | in | ||
| ) |
Write a pc_bignum as a 256-byte big-endian array.
| bytes | Destination buffer (exactly 256 bytes). |
| in | Source bignum. |
Definition at line 96 of file bignum.cpp.
References pc_bignum::d, and PC_BN_LIMBS.
Referenced by ssh_kexdh_handle().
Compare two pc_bignum values.
Definition at line 108 of file bignum.cpp.
References bn_cmp_raw(), pc_bignum::d, and PC_BN_LIMBS.
Referenced by bn_dh_validate().
| int bn_is_zero | ( | const pc_bignum * | a | ) |
Return non-zero if a is zero (all limbs zero).
Definition at line 113 of file bignum.cpp.
References pc_bignum::d, and PC_BN_LIMBS.
| int bn_cmp_raw | ( | const uint32_t * | a, |
| const uint32_t * | b, | ||
| int | n | ||
| ) |
Compute out = base^exp mod group14_p.
Uses Montgomery modular exponentiation with left-to-right binary scan. Borrows one working set for all temporaries; it is wiped when released.
On Arduino the computation is delegated to mbedtls_mpi_exp_mod() which uses hardware multiplication and blinding.
| out | Result (base^exp mod p, 2048-bit). |
| base | Base value; must satisfy 1 < base < p-1. |
| exp | Exponent (e.g. the 2048-bit private DH scalar y). |
Compare two n-limb magnitudes: -1, 0 or 1. Shared with the backends.
Definition at line 64 of file bignum.cpp.
Referenced by bn_cmp().
Definition at line 195 of file portable_bignum.cpp.
References pc_span::buf, pc_bignum::d, PC_BN_LIMBS, pc_span_ok(), PC_CRYPTO_HOT::Group14Ctx::r1, PC_CRYPTO_HOT::Group14Ctx::r2, and SecureBorrow::span().
Referenced by ssh_dh_generate(), and ssh_kexdh_handle().
| int bn_dh_validate | ( | const pc_bignum * | v | ) |
Validate a received DH public value.
RFC 4253 §8: the received value e (or f) must satisfy 1 < e < p-1. Returns 0 if the value is valid, -1 otherwise.
| v | Received public DH value. |
Definition at line 125 of file bignum.cpp.
References bn_cmp(), pc_bignum::d, group14_p, and PC_BN_LIMBS.
Referenced by ssh_kexdh_handle().
|
extern |
The RFC 3526 MODP group-14 prime (2048-bit).
Definition at line 42 of file bignum.cpp.
Referenced by bn_dh_validate().
|
extern |
Generator for group-14: g = 2.
Definition at line 54 of file bignum.cpp.
Referenced by ssh_dh_generate().