Loading .kdev4/libnetplus.kdev4 +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x Build Directory Count=2 Current Build Directory Index-Host System=0 Current Build Directory Index-Host-System=1 Temporary Build Directory Index=1 [CMake][CMake Build Directory 0] Build Directory Path=/local/jan/Projects/libnetplus/build Loading @@ -26,5 +27,8 @@ Extra Arguments= Install Directory=/usr/local Runtime=Host-System [MakeBuilder] Make Binary=ninja [Project] VersionControlSupport=kdevgit src/crypto/curve25519.cpp +71 −45 Original line number Diff line number Diff line Loading @@ -7,23 +7,34 @@ namespace netplus { FieldElement::FieldElement() : limbs(10, 0) {} FieldElement::FieldElement() { limbs.fill(0); } FieldElement::FieldElement(int v) : limbs(10, 0) { limbs[0] = v; } FieldElement::FieldElement(int v) { limbs.fill(0); limbs[0] = v; } FieldElement::FieldElement(const std::vector<int32_t>& v) : limbs(v) { if (limbs.size() != 10) limbs.resize(10, 0); FieldElement::FieldElement(const std::vector<int32_t>& v) { limbs.fill(0); for (size_t i = 0; i < 10 && i < v.size(); ++i) limbs[i] = v[i]; } FieldElement::FieldElement(const FieldElement& src) : limbs(src.limbs) {} FieldElement& FieldElement::operator=(const std::vector<int32_t>& v) { limbs = v; if (limbs.size() != 10) limbs.resize(10, 0); limbs.fill(0); for (size_t i = 0; i < 10 && i < v.size(); ++i) limbs[i] = v[i]; return *this; } FieldElement FieldElement::operator+(const FieldElement& other) const { FieldElement r; for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] + other.limbs[i]; for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] + other.limbs[i]; return r; } Loading @@ -35,8 +46,8 @@ FieldElement FieldElement::operator-(const FieldElement& other) const { } FieldElement FieldElement::operator*(const FieldElement& g) const { const int32_t* f = limbs.data(); const int32_t* h = g.limbs.data(); const int64_t* f = limbs.data(); const int64_t* h = g.limbs.data(); int64_t f0 = f[0]; int64_t f1 = f[1]; Loading Loading @@ -102,25 +113,24 @@ FieldElement FieldElement::operator*(const FieldElement& g) const { carry0 = (h0 + (1LL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; FieldElement r; r.limbs[0] = (int32_t)h0; r.limbs[1] = (int32_t)h1; r.limbs[2] = (int32_t)h2; r.limbs[3] = (int32_t)h3; r.limbs[4] = (int32_t)h4; r.limbs[5] = (int32_t)h5; r.limbs[6] = (int32_t)h6; r.limbs[7] = (int32_t)h7; r.limbs[8] = (int32_t)h8; r.limbs[9] = (int32_t)h9; r.limbs[0] = h0; r.limbs[1] = h1; r.limbs[2] = h2; r.limbs[3] = h3; r.limbs[4] = h4; r.limbs[5] = h5; r.limbs[6] = h6; r.limbs[7] = h7; r.limbs[8] = h8; r.limbs[9] = h9; return r; } FieldElement FieldElement::operator*(int32_t scalar) const { FieldElement r; int64_t sc = scalar; for (int i = 0; i < 10; ++i) { r.limbs[i] = (int32_t)((int64_t)limbs[i] * sc); } for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] * sc; return r; } Loading Loading @@ -202,7 +212,7 @@ FieldElement FieldElement::invert() const { return t * z11; } void FieldElement::to_bytes(std::vector<uint8_t>& s) const { std::vector<uint8_t> FieldElement::to_bytes() const { int64_t h[10]; for (int i = 0; i < 10; ++i) h[i] = limbs[i]; Loading Loading @@ -233,11 +243,18 @@ void FieldElement::to_bytes(std::vector<uint8_t>& s) const { int64_t carry6 = h[6] >> 26; h[7] += carry6; h[6] -= carry6 << 26; int64_t carry7 = h[7] >> 25; h[8] += carry7; h[7] -= carry7 << 25; int64_t carry8 = h[8] >> 26; h[9] += carry8; h[8] -= carry8 << 26; int64_t carry9 = h[9] >> 25; h[9] -= carry9 << 25; int64_t carry9 = h[9] >> 25; h[0] += carry9 * 19; h[9] -= carry9 << 25; int64_t carry0b = h[0] >> 26; h[1] += carry0b; h[0] -= carry0b << 26; // --------------------------------------------------------------------- // Pack into 32 bytes little-endian (canonical ref10 mapping) // --------------------------------------------------------------------- std::vector<uint8_t> s; s.assign(32, 0); s[0] = (uint8_t)(h[0] >> 0); Loading Loading @@ -272,6 +289,7 @@ void FieldElement::to_bytes(std::vector<uint8_t>& s) const { s[29] = (uint8_t)(h[9] >> 2); s[30] = (uint8_t)(h[9] >> 10); s[31] = (uint8_t)(h[9] >> 18); return s; } bool scalarmult_curve25519(std::vector<uint8_t> &out, Loading @@ -279,20 +297,27 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, const std::vector<uint8_t> &point_u) { auto cswap = [&](FieldElement& a, FieldElement& b, int swap) { int32_t mask = -swap; uint64_t mask = (uint64_t)-(int64_t)swap; // 0 or all-ones for (int i = 0; i < 10; ++i) { int32_t t = mask & (a.limbs[i] ^ b.limbs[i]); a.limbs[i] ^= t; b.limbs[i] ^= t; uint64_t ai = (uint64_t)a.limbs[i]; uint64_t bi = (uint64_t)b.limbs[i]; uint64_t t = mask & (ai ^ bi); a.limbs[i] = (int64_t)(ai ^ t); b.limbs[i] = (int64_t)(bi ^ t); } }; auto load_3 = [&](const uint8_t *in) { return in[0] | (in[1] << 8) | (in[2] << 16); auto load_3 = [&](const uint8_t *in) -> uint32_t { return (uint32_t)in[0] | ((uint32_t)in[1] << 8) | ((uint32_t)in[2] << 16); }; auto load_4 = [&](const uint8_t *in) { return in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24); auto load_4 = [&](const uint8_t *in) -> uint32_t { return (uint32_t)in[0] | ((uint32_t)in[1] << 8) | ((uint32_t)in[2] << 16) | ((uint32_t)in[3] << 24); }; // Check input sizes Loading @@ -308,17 +333,18 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, // Decode u-coordinate (little-endian) FieldElement u; u.zero(); // Decode u-coordinate (little-endian) into 10 limbs // Decode u-coordinate (little-endian) into 10 limbs (ref10 fe_frombytes) u.limbs[0] = load_4(&point_u[0]) & 0x3ffffff; u.limbs[1] = (load_4(&point_u[3]) >> 2) & 0x1ffffff; u.limbs[2] = (load_3(&point_u[6]) << 3) & 0x3ffffff; u.limbs[3] = (load_3(&point_u[9]) >> 1) & 0x1ffffff; u.limbs[4] = (load_4(&point_u[12]) >> 6) & 0x3ffffff; u.limbs[5] = (load_3(&point_u[16]) << 5) & 0x1ffffff; u.limbs[6] = (load_3(&point_u[19]) >> 2) & 0x3ffffff; u.limbs[7] = (load_4(&point_u[22]) >> 7) & 0x1ffffff; u.limbs[8] = (load_4(&point_u[25]) >> 3) & 0x3ffffff; u.limbs[9] = (load_3(&point_u[28]) >> 0) & 0x1ffffff; u.limbs[1] = (load_3(&point_u[3]) >> 2) & 0x1ffffff; u.limbs[2] = (load_3(&point_u[6]) >> 3) & 0x3ffffff; u.limbs[3] = (load_3(&point_u[9]) >> 5) & 0x1ffffff; u.limbs[4] = (load_3(&point_u[12]) >> 6) & 0x3ffffff; u.limbs[5] = load_4(&point_u[16]) & 0x1ffffff; u.limbs[6] = (load_3(&point_u[19]) >> 1) & 0x3ffffff; u.limbs[7] = (load_3(&point_u[22]) >> 3) & 0x1ffffff; u.limbs[8] = (load_3(&point_u[25]) >> 4) & 0x3ffffff; u.limbs[9] = (load_3(&point_u[28]) >> 6) & 0x1ffffff; // Initialize ladder FieldElement x1 = u; Loading Loading @@ -361,7 +387,7 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, // Compute u = x2 / z2 FieldElement z2inv = z2.invert(); FieldElement result = x2 * z2inv; result.to_bytes(out); out=result.to_bytes(); return true; } Loading src/crypto/curve25519.h +15 −10 Original line number Diff line number Diff line #include <vector> #include <cstdint> #include <algorithm> #pragma once #include <array> #include <cstdint> #include <vector> #include <algorithm> namespace netplus { class FieldElement { public: std::vector<int32_t> limbs; std::array<int64_t, 10> limbs; FieldElement(); FieldElement(int v); FieldElement(const std::vector<int32_t>& v); FieldElement(const FieldElement& src); FieldElement& operator=(const std::vector<int32_t>& v); FieldElement operator+(const FieldElement& other) const; FieldElement operator-(const FieldElement& other) const; FieldElement operator*(const FieldElement& other) const; FieldElement operator*(int32_t scalar) const; bool operator==(const FieldElement& other) const; void zero(); void one(); void to_bytes(std::vector<uint8_t>& out) const; FieldElement invert() const; private: friend FieldElement operator*(int32_t scalar, const FieldElement& fe); std::vector<uint8_t> to_bytes() const; }; FieldElement operator*(int32_t scalar, const FieldElement& fe); bool scalarmult_curve25519(std::vector<uint8_t> &out, const std::vector<uint8_t> &scalar, Loading @@ -36,4 +41,4 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, bool scalarmult_curve25519_base(std::vector<uint8_t> &out, const std::vector<uint8_t> &scalar); }; // namespace netplus } // namespace netplus src/ssl.cpp +0 −15 Original line number Diff line number Diff line Loading @@ -292,21 +292,6 @@ namespace netplus { return !nBE.empty() && !eBE.empty() && !dBE.empty(); } static P256Point p256_make_keypair(uint8_t priv[32]) { for (;;) { netplus::fillRandomBytes(priv, 32); bool allZero = true; for (int i = 0; i < 32; i++) { if (priv[i] != 0) { allZero = false; break; } } if (allZero) continue; return netplus::scalar_mul_G(priv); } } static inline void tls13_make_nonce(uint8_t out[12], const uint8_t iv[12], uint64_t seq) { std::memcpy(out, iv, 12); Loading test/ecc.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -768,6 +768,7 @@ int main() { if(!test_mont_roundtrip_big(netplus::P256_G().x)) fails++; if(!test_mont_roundtrip_big(netplus::P256_G().y)) fails++; if(!test_fp_mul_vs_modp()) fails++; if(!test_ecc_suite()) fails++; if(!test_ecdh_symmetry()) fails++; Loading Loading
.kdev4/libnetplus.kdev4 +4 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x Build Directory Count=2 Current Build Directory Index-Host System=0 Current Build Directory Index-Host-System=1 Temporary Build Directory Index=1 [CMake][CMake Build Directory 0] Build Directory Path=/local/jan/Projects/libnetplus/build Loading @@ -26,5 +27,8 @@ Extra Arguments= Install Directory=/usr/local Runtime=Host-System [MakeBuilder] Make Binary=ninja [Project] VersionControlSupport=kdevgit
src/crypto/curve25519.cpp +71 −45 Original line number Diff line number Diff line Loading @@ -7,23 +7,34 @@ namespace netplus { FieldElement::FieldElement() : limbs(10, 0) {} FieldElement::FieldElement() { limbs.fill(0); } FieldElement::FieldElement(int v) : limbs(10, 0) { limbs[0] = v; } FieldElement::FieldElement(int v) { limbs.fill(0); limbs[0] = v; } FieldElement::FieldElement(const std::vector<int32_t>& v) : limbs(v) { if (limbs.size() != 10) limbs.resize(10, 0); FieldElement::FieldElement(const std::vector<int32_t>& v) { limbs.fill(0); for (size_t i = 0; i < 10 && i < v.size(); ++i) limbs[i] = v[i]; } FieldElement::FieldElement(const FieldElement& src) : limbs(src.limbs) {} FieldElement& FieldElement::operator=(const std::vector<int32_t>& v) { limbs = v; if (limbs.size() != 10) limbs.resize(10, 0); limbs.fill(0); for (size_t i = 0; i < 10 && i < v.size(); ++i) limbs[i] = v[i]; return *this; } FieldElement FieldElement::operator+(const FieldElement& other) const { FieldElement r; for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] + other.limbs[i]; for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] + other.limbs[i]; return r; } Loading @@ -35,8 +46,8 @@ FieldElement FieldElement::operator-(const FieldElement& other) const { } FieldElement FieldElement::operator*(const FieldElement& g) const { const int32_t* f = limbs.data(); const int32_t* h = g.limbs.data(); const int64_t* f = limbs.data(); const int64_t* h = g.limbs.data(); int64_t f0 = f[0]; int64_t f1 = f[1]; Loading Loading @@ -102,25 +113,24 @@ FieldElement FieldElement::operator*(const FieldElement& g) const { carry0 = (h0 + (1LL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; FieldElement r; r.limbs[0] = (int32_t)h0; r.limbs[1] = (int32_t)h1; r.limbs[2] = (int32_t)h2; r.limbs[3] = (int32_t)h3; r.limbs[4] = (int32_t)h4; r.limbs[5] = (int32_t)h5; r.limbs[6] = (int32_t)h6; r.limbs[7] = (int32_t)h7; r.limbs[8] = (int32_t)h8; r.limbs[9] = (int32_t)h9; r.limbs[0] = h0; r.limbs[1] = h1; r.limbs[2] = h2; r.limbs[3] = h3; r.limbs[4] = h4; r.limbs[5] = h5; r.limbs[6] = h6; r.limbs[7] = h7; r.limbs[8] = h8; r.limbs[9] = h9; return r; } FieldElement FieldElement::operator*(int32_t scalar) const { FieldElement r; int64_t sc = scalar; for (int i = 0; i < 10; ++i) { r.limbs[i] = (int32_t)((int64_t)limbs[i] * sc); } for (int i = 0; i < 10; ++i) r.limbs[i] = limbs[i] * sc; return r; } Loading Loading @@ -202,7 +212,7 @@ FieldElement FieldElement::invert() const { return t * z11; } void FieldElement::to_bytes(std::vector<uint8_t>& s) const { std::vector<uint8_t> FieldElement::to_bytes() const { int64_t h[10]; for (int i = 0; i < 10; ++i) h[i] = limbs[i]; Loading Loading @@ -233,11 +243,18 @@ void FieldElement::to_bytes(std::vector<uint8_t>& s) const { int64_t carry6 = h[6] >> 26; h[7] += carry6; h[6] -= carry6 << 26; int64_t carry7 = h[7] >> 25; h[8] += carry7; h[7] -= carry7 << 25; int64_t carry8 = h[8] >> 26; h[9] += carry8; h[8] -= carry8 << 26; int64_t carry9 = h[9] >> 25; h[9] -= carry9 << 25; int64_t carry9 = h[9] >> 25; h[0] += carry9 * 19; h[9] -= carry9 << 25; int64_t carry0b = h[0] >> 26; h[1] += carry0b; h[0] -= carry0b << 26; // --------------------------------------------------------------------- // Pack into 32 bytes little-endian (canonical ref10 mapping) // --------------------------------------------------------------------- std::vector<uint8_t> s; s.assign(32, 0); s[0] = (uint8_t)(h[0] >> 0); Loading Loading @@ -272,6 +289,7 @@ void FieldElement::to_bytes(std::vector<uint8_t>& s) const { s[29] = (uint8_t)(h[9] >> 2); s[30] = (uint8_t)(h[9] >> 10); s[31] = (uint8_t)(h[9] >> 18); return s; } bool scalarmult_curve25519(std::vector<uint8_t> &out, Loading @@ -279,20 +297,27 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, const std::vector<uint8_t> &point_u) { auto cswap = [&](FieldElement& a, FieldElement& b, int swap) { int32_t mask = -swap; uint64_t mask = (uint64_t)-(int64_t)swap; // 0 or all-ones for (int i = 0; i < 10; ++i) { int32_t t = mask & (a.limbs[i] ^ b.limbs[i]); a.limbs[i] ^= t; b.limbs[i] ^= t; uint64_t ai = (uint64_t)a.limbs[i]; uint64_t bi = (uint64_t)b.limbs[i]; uint64_t t = mask & (ai ^ bi); a.limbs[i] = (int64_t)(ai ^ t); b.limbs[i] = (int64_t)(bi ^ t); } }; auto load_3 = [&](const uint8_t *in) { return in[0] | (in[1] << 8) | (in[2] << 16); auto load_3 = [&](const uint8_t *in) -> uint32_t { return (uint32_t)in[0] | ((uint32_t)in[1] << 8) | ((uint32_t)in[2] << 16); }; auto load_4 = [&](const uint8_t *in) { return in[0] | (in[1] << 8) | (in[2] << 16) | (in[3] << 24); auto load_4 = [&](const uint8_t *in) -> uint32_t { return (uint32_t)in[0] | ((uint32_t)in[1] << 8) | ((uint32_t)in[2] << 16) | ((uint32_t)in[3] << 24); }; // Check input sizes Loading @@ -308,17 +333,18 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, // Decode u-coordinate (little-endian) FieldElement u; u.zero(); // Decode u-coordinate (little-endian) into 10 limbs // Decode u-coordinate (little-endian) into 10 limbs (ref10 fe_frombytes) u.limbs[0] = load_4(&point_u[0]) & 0x3ffffff; u.limbs[1] = (load_4(&point_u[3]) >> 2) & 0x1ffffff; u.limbs[2] = (load_3(&point_u[6]) << 3) & 0x3ffffff; u.limbs[3] = (load_3(&point_u[9]) >> 1) & 0x1ffffff; u.limbs[4] = (load_4(&point_u[12]) >> 6) & 0x3ffffff; u.limbs[5] = (load_3(&point_u[16]) << 5) & 0x1ffffff; u.limbs[6] = (load_3(&point_u[19]) >> 2) & 0x3ffffff; u.limbs[7] = (load_4(&point_u[22]) >> 7) & 0x1ffffff; u.limbs[8] = (load_4(&point_u[25]) >> 3) & 0x3ffffff; u.limbs[9] = (load_3(&point_u[28]) >> 0) & 0x1ffffff; u.limbs[1] = (load_3(&point_u[3]) >> 2) & 0x1ffffff; u.limbs[2] = (load_3(&point_u[6]) >> 3) & 0x3ffffff; u.limbs[3] = (load_3(&point_u[9]) >> 5) & 0x1ffffff; u.limbs[4] = (load_3(&point_u[12]) >> 6) & 0x3ffffff; u.limbs[5] = load_4(&point_u[16]) & 0x1ffffff; u.limbs[6] = (load_3(&point_u[19]) >> 1) & 0x3ffffff; u.limbs[7] = (load_3(&point_u[22]) >> 3) & 0x1ffffff; u.limbs[8] = (load_3(&point_u[25]) >> 4) & 0x3ffffff; u.limbs[9] = (load_3(&point_u[28]) >> 6) & 0x1ffffff; // Initialize ladder FieldElement x1 = u; Loading Loading @@ -361,7 +387,7 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, // Compute u = x2 / z2 FieldElement z2inv = z2.invert(); FieldElement result = x2 * z2inv; result.to_bytes(out); out=result.to_bytes(); return true; } Loading
src/crypto/curve25519.h +15 −10 Original line number Diff line number Diff line #include <vector> #include <cstdint> #include <algorithm> #pragma once #include <array> #include <cstdint> #include <vector> #include <algorithm> namespace netplus { class FieldElement { public: std::vector<int32_t> limbs; std::array<int64_t, 10> limbs; FieldElement(); FieldElement(int v); FieldElement(const std::vector<int32_t>& v); FieldElement(const FieldElement& src); FieldElement& operator=(const std::vector<int32_t>& v); FieldElement operator+(const FieldElement& other) const; FieldElement operator-(const FieldElement& other) const; FieldElement operator*(const FieldElement& other) const; FieldElement operator*(int32_t scalar) const; bool operator==(const FieldElement& other) const; void zero(); void one(); void to_bytes(std::vector<uint8_t>& out) const; FieldElement invert() const; private: friend FieldElement operator*(int32_t scalar, const FieldElement& fe); std::vector<uint8_t> to_bytes() const; }; FieldElement operator*(int32_t scalar, const FieldElement& fe); bool scalarmult_curve25519(std::vector<uint8_t> &out, const std::vector<uint8_t> &scalar, Loading @@ -36,4 +41,4 @@ bool scalarmult_curve25519(std::vector<uint8_t> &out, bool scalarmult_curve25519_base(std::vector<uint8_t> &out, const std::vector<uint8_t> &scalar); }; // namespace netplus } // namespace netplus
src/ssl.cpp +0 −15 Original line number Diff line number Diff line Loading @@ -292,21 +292,6 @@ namespace netplus { return !nBE.empty() && !eBE.empty() && !dBE.empty(); } static P256Point p256_make_keypair(uint8_t priv[32]) { for (;;) { netplus::fillRandomBytes(priv, 32); bool allZero = true; for (int i = 0; i < 32; i++) { if (priv[i] != 0) { allZero = false; break; } } if (allZero) continue; return netplus::scalar_mul_G(priv); } } static inline void tls13_make_nonce(uint8_t out[12], const uint8_t iv[12], uint64_t seq) { std::memcpy(out, iv, 12); Loading
test/ecc.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -768,6 +768,7 @@ int main() { if(!test_mont_roundtrip_big(netplus::P256_G().x)) fails++; if(!test_mont_roundtrip_big(netplus::P256_G().y)) fails++; if(!test_fp_mul_vs_modp()) fails++; if(!test_ecc_suite()) fails++; if(!test_ecdh_symmetry()) fails++; Loading