Loading src/crypto/rsa.cpp +57 −42 Original line number Diff line number Diff line Loading @@ -901,54 +901,69 @@ namespace netplus { return a; } rsa::bigInt rsa::modInverse(const bigInt& k, const bigInt& pm) { // 1. Initialize local constants properly to avoid ambiguity bigInt one((uint32_t)1, (size_t)1); bigInt u = k; bigInt v = pm; // Ensure capacity is sufficient for intermediate additions size_t cap = pm.capacity + 1; bigInt x1((size_t)cap); bigInt x2((size_t)cap); x1.data[0] = 1; x1.used = 1; // x2 is initialized to 0 by the constructor // 2. Binary Extended Euclidean Algorithm while (compare(u, one) != 0 && compare(v, one) != 0) { while (u.isEven()) { u.divideByTwo(); if (x1.isEven()) { x1.divideByTwo(); rsa::bigInt rsa::modInverse(const bigInt& a, const bigInt& m) { // Extended Euclidean Algorithm: find x such that a*x ≡ 1 (mod m) // Tracks sign separately since bigInt is unsigned. bigInt old_r = m; bigInt r = a; // |old_s| = 0 (positive), |s| = 1 (positive) bigInt old_s_abs(m.capacity + 1); old_s_abs.data[0] = 0; old_s_abs.used = 1; bool old_s_neg = false; bigInt s_abs(m.capacity + 1); s_abs.data[0] = 1; s_abs.used = 1; bool s_neg = false; while (!r.isZero()) { bigInt q, rem; divide(old_r, r, q, rem); old_r = r; r = rem; // temp = q * |s| bigInt temp(q.used + s_abs.used + 1); multiply(q, s_abs, temp); // new_s = old_s - q * s (signed arithmetic) bigInt new_abs; bool new_neg; if (old_s_neg == s_neg) { // Same sign: subtract magnitudes int cmp = compare(old_s_abs, temp); if (cmp >= 0) { new_abs = bigInt(old_s_abs.capacity); subtract(old_s_abs, temp, new_abs); new_neg = old_s_neg; } else { add(x1, pm, x1); x1.divideByTwo(); new_abs = bigInt(temp.capacity); subtract(temp, old_s_abs, new_abs); new_neg = !old_s_neg; } } while (v.isEven()) { v.divideByTwo(); if (x2.isEven()) { x2.divideByTwo(); } else { add(x2, pm, x2); x2.divideByTwo(); } } if (compare(u, v) >= 0) { subtract(u, v, u); if (compare(x1, x2) < 0) add(x1, pm, x1); subtract(x1, x2, x1); } else { subtract(v, u, v); if (compare(x2, x1) < 0) add(x2, pm, x2); subtract(x2, x1, x2); // Different signs: add magnitudes new_abs = bigInt(std::max(old_s_abs.capacity, temp.capacity) + 1); add(old_s_abs, temp, new_abs); new_neg = old_s_neg; } old_s_abs = s_abs; old_s_neg = s_neg; s_abs = new_abs; s_neg = new_neg; } return (compare(u, one) == 0) ? x1 : x2; // If result is negative, add m to make it positive if (old_s_neg) { bigInt result(m.capacity + 1); subtract(m, old_s_abs, result); return result; } return old_s_abs; } bool rsa::isProbablyPrime(const bigInt& n, int k) { Loading Loading
src/crypto/rsa.cpp +57 −42 Original line number Diff line number Diff line Loading @@ -901,54 +901,69 @@ namespace netplus { return a; } rsa::bigInt rsa::modInverse(const bigInt& k, const bigInt& pm) { // 1. Initialize local constants properly to avoid ambiguity bigInt one((uint32_t)1, (size_t)1); bigInt u = k; bigInt v = pm; // Ensure capacity is sufficient for intermediate additions size_t cap = pm.capacity + 1; bigInt x1((size_t)cap); bigInt x2((size_t)cap); x1.data[0] = 1; x1.used = 1; // x2 is initialized to 0 by the constructor // 2. Binary Extended Euclidean Algorithm while (compare(u, one) != 0 && compare(v, one) != 0) { while (u.isEven()) { u.divideByTwo(); if (x1.isEven()) { x1.divideByTwo(); rsa::bigInt rsa::modInverse(const bigInt& a, const bigInt& m) { // Extended Euclidean Algorithm: find x such that a*x ≡ 1 (mod m) // Tracks sign separately since bigInt is unsigned. bigInt old_r = m; bigInt r = a; // |old_s| = 0 (positive), |s| = 1 (positive) bigInt old_s_abs(m.capacity + 1); old_s_abs.data[0] = 0; old_s_abs.used = 1; bool old_s_neg = false; bigInt s_abs(m.capacity + 1); s_abs.data[0] = 1; s_abs.used = 1; bool s_neg = false; while (!r.isZero()) { bigInt q, rem; divide(old_r, r, q, rem); old_r = r; r = rem; // temp = q * |s| bigInt temp(q.used + s_abs.used + 1); multiply(q, s_abs, temp); // new_s = old_s - q * s (signed arithmetic) bigInt new_abs; bool new_neg; if (old_s_neg == s_neg) { // Same sign: subtract magnitudes int cmp = compare(old_s_abs, temp); if (cmp >= 0) { new_abs = bigInt(old_s_abs.capacity); subtract(old_s_abs, temp, new_abs); new_neg = old_s_neg; } else { add(x1, pm, x1); x1.divideByTwo(); new_abs = bigInt(temp.capacity); subtract(temp, old_s_abs, new_abs); new_neg = !old_s_neg; } } while (v.isEven()) { v.divideByTwo(); if (x2.isEven()) { x2.divideByTwo(); } else { add(x2, pm, x2); x2.divideByTwo(); } } if (compare(u, v) >= 0) { subtract(u, v, u); if (compare(x1, x2) < 0) add(x1, pm, x1); subtract(x1, x2, x1); } else { subtract(v, u, v); if (compare(x2, x1) < 0) add(x2, pm, x2); subtract(x2, x1, x2); // Different signs: add magnitudes new_abs = bigInt(std::max(old_s_abs.capacity, temp.capacity) + 1); add(old_s_abs, temp, new_abs); new_neg = old_s_neg; } old_s_abs = s_abs; old_s_neg = s_neg; s_abs = new_abs; s_neg = new_neg; } return (compare(u, one) == 0) ? x1 : x2; // If result is negative, add m to make it positive if (old_s_neg) { bigInt result(m.capacity + 1); subtract(m, old_s_abs, result); return result; } return old_s_abs; } bool rsa::isProbablyPrime(const bigInt& n, int k) { Loading