Loading debian/changelog +9 −0 Original line number Diff line number Diff line libnetplus (20260425+2) unstable; urgency=medium * RSA bigInt: switch from fixed 32-bit limbs to portable limb_t/dlimb_t typedefs — 64-bit limbs with __uint128_t accumulator on GCC/Clang, 32-bit fallback on MSVC. Halves limb count for RSA-2048 (64→32), yielding ~4x fewer inner-loop iterations in Montgomery CIOS. -- Jan Koester <jan.koester@tuxist.de> Sat, 25 Apr 2026 14:00:00 +0200 libnetplus (20260425+1) unstable; urgency=medium * RSA: replace separate multiply + reduce with fused CIOS Loading src/crypto/rsa.cpp +169 −150 File changed.Preview size limit exceeded, changes collapsed. Show changes src/crypto/rsa.h +20 −9 Original line number Diff line number Diff line Loading @@ -32,23 +32,34 @@ #pragma once // Portable limb types: 64-bit on GCC/Clang, 32-bit fallback on MSVC #if defined(__SIZEOF_INT128__) using limb_t = uint64_t; using dlimb_t = __uint128_t; #define LIMB_BITS 64 #else using limb_t = uint32_t; using dlimb_t = uint64_t; #define LIMB_BITS 32 #endif namespace netplus { class rsa { public: class bigInt { public: std::unique_ptr<uint32_t[]> data; size_t used; // number of 32-bit words used std::unique_ptr<limb_t[]> data; size_t used; // number of limb_t words used size_t capacity; explicit bigInt(size_t cap_words = 64) : used(1), capacity(std::max<size_t>(1, cap_words)) { data = std::make_unique<uint32_t[]>(capacity); std::fill(data.get(), data.get() + capacity, 0); data = std::make_unique<limb_t[]>(capacity); std::fill(data.get(), data.get() + capacity, limb_t(0)); } bigInt(uint32_t val, size_t cap) : used(1), capacity(std::max<size_t>(1, cap)) { data = std::make_unique<uint32_t[]>(capacity); std::fill(data.get(), data.get() + capacity, 0); data = std::make_unique<limb_t[]>(capacity); std::fill(data.get(), data.get() + capacity, limb_t(0)); data[0] = val; } Loading Loading @@ -138,12 +149,12 @@ namespace netplus { static bigInt modPow(const bigInt& base, const bigInt& exp, const bigInt& mod); static bigInt modInverse(const bigInt& e, const bigInt& phi); static bigInt gcd(bigInt a, bigInt b); static uint32_t calculateNPrime(uint32_t n0); static limb_t calculateNPrime(limb_t n0); static bigInt calculateRMod(const bigInt& mod); static bigInt calculateR2Mod(const bigInt& mod); static bigInt montgomeryMultiply(const bigInt& a, const bigInt& b, const bigInt& mod, uint32_t n_prime); static bigInt montgomeryMultiply(const bigInt& a, const bigInt& b, const bigInt& mod, limb_t n_prime); static void montgomeryMultiply_into(const bigInt& a, const bigInt& b, const bigInt& mod, uint32_t n_prime, const bigInt& mod, limb_t n_prime, bigInt& scratch, bigInt& out); friend class x509cert; friend class tls; Loading Loading
debian/changelog +9 −0 Original line number Diff line number Diff line libnetplus (20260425+2) unstable; urgency=medium * RSA bigInt: switch from fixed 32-bit limbs to portable limb_t/dlimb_t typedefs — 64-bit limbs with __uint128_t accumulator on GCC/Clang, 32-bit fallback on MSVC. Halves limb count for RSA-2048 (64→32), yielding ~4x fewer inner-loop iterations in Montgomery CIOS. -- Jan Koester <jan.koester@tuxist.de> Sat, 25 Apr 2026 14:00:00 +0200 libnetplus (20260425+1) unstable; urgency=medium * RSA: replace separate multiply + reduce with fused CIOS Loading
src/crypto/rsa.cpp +169 −150 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/crypto/rsa.h +20 −9 Original line number Diff line number Diff line Loading @@ -32,23 +32,34 @@ #pragma once // Portable limb types: 64-bit on GCC/Clang, 32-bit fallback on MSVC #if defined(__SIZEOF_INT128__) using limb_t = uint64_t; using dlimb_t = __uint128_t; #define LIMB_BITS 64 #else using limb_t = uint32_t; using dlimb_t = uint64_t; #define LIMB_BITS 32 #endif namespace netplus { class rsa { public: class bigInt { public: std::unique_ptr<uint32_t[]> data; size_t used; // number of 32-bit words used std::unique_ptr<limb_t[]> data; size_t used; // number of limb_t words used size_t capacity; explicit bigInt(size_t cap_words = 64) : used(1), capacity(std::max<size_t>(1, cap_words)) { data = std::make_unique<uint32_t[]>(capacity); std::fill(data.get(), data.get() + capacity, 0); data = std::make_unique<limb_t[]>(capacity); std::fill(data.get(), data.get() + capacity, limb_t(0)); } bigInt(uint32_t val, size_t cap) : used(1), capacity(std::max<size_t>(1, cap)) { data = std::make_unique<uint32_t[]>(capacity); std::fill(data.get(), data.get() + capacity, 0); data = std::make_unique<limb_t[]>(capacity); std::fill(data.get(), data.get() + capacity, limb_t(0)); data[0] = val; } Loading Loading @@ -138,12 +149,12 @@ namespace netplus { static bigInt modPow(const bigInt& base, const bigInt& exp, const bigInt& mod); static bigInt modInverse(const bigInt& e, const bigInt& phi); static bigInt gcd(bigInt a, bigInt b); static uint32_t calculateNPrime(uint32_t n0); static limb_t calculateNPrime(limb_t n0); static bigInt calculateRMod(const bigInt& mod); static bigInt calculateR2Mod(const bigInt& mod); static bigInt montgomeryMultiply(const bigInt& a, const bigInt& b, const bigInt& mod, uint32_t n_prime); static bigInt montgomeryMultiply(const bigInt& a, const bigInt& b, const bigInt& mod, limb_t n_prime); static void montgomeryMultiply_into(const bigInt& a, const bigInt& b, const bigInt& mod, uint32_t n_prime, const bigInt& mod, limb_t n_prime, bigInt& scratch, bigInt& out); friend class x509cert; friend class tls; Loading