Loading src/crypto/curve25519.cpp +134 −123 Original line number Diff line number Diff line // curve25519.cpp #include "curve25519.h" #include <stdint.h> #include <string.h> namespace netplus { static inline uint32_t load32(const uint8_t *p) { return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); } // ---------- field element (10 limbs) ---------- typedef int32_t fe[10]; static inline void store32(uint8_t *p, uint32_t v) { p[0] = (uint8_t)(v); p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); static inline uint32_t load32(const uint8_t *x) { return (uint32_t)x[0] | ((uint32_t)x[1] << 8) | ((uint32_t)x[2] << 16) | ((uint32_t)x[3] << 24); } // Field element radix 2^25.5 typedef int32_t fe[10]; static void fe_0(fe h) { memset(h, 0, sizeof(fe)); } static void fe_1(fe h) { fe_0(h); h[0] = 1; } static void fe_copy(fe h, const fe f) { memcpy(h, f, sizeof(fe)); } Loading @@ -32,30 +27,32 @@ static void fe_sub(fe h, const fe f, const fe g) { } static void fe_cswap(fe f, fe g, uint32_t b) { b = -b; b = (uint32_t)(-((int32_t)b)); for (int i=0;i<10;i++) { int32_t x = b & (f[i] ^ g[i]); int32_t x = (int32_t)(b & (uint32_t)(f[i] ^ g[i])); f[i] ^= x; g[i] ^= x; } } // carry/reduce static void fe_carry(fe h) { int64_t c; c = (h[0] + ((int64_t)1<<25)) >> 26; h[1] += c; h[0] -= c<<26; c = (h[1] + ((int64_t)1<<24)) >> 25; h[2] += c; h[1] -= c<<25; c = (h[2] + ((int64_t)1<<25)) >> 26; h[3] += c; h[2] -= c<<26; c = (h[3] + ((int64_t)1<<24)) >> 25; h[4] += c; h[3] -= c<<25; c = (h[4] + ((int64_t)1<<25)) >> 26; h[5] += c; h[4] -= c<<26; c = (h[5] + ((int64_t)1<<24)) >> 25; h[6] += c; h[5] -= c<<25; c = (h[6] + ((int64_t)1<<25)) >> 26; h[7] += c; h[6] -= c<<26; c = (h[7] + ((int64_t)1<<24)) >> 25; h[8] += c; h[7] -= c<<25; c = (h[8] + ((int64_t)1<<25)) >> 26; h[9] += c; h[8] -= c<<26; c = (h[9] + ((int64_t)1<<24)) >> 25; h[0] += c*19; h[9] -= c<<25; c = (h[0] + ((int64_t)1<<25)) >> 26; h[1] += c; h[0] -= c<<26; c = (h[0] + (1LL<<25)) >> 26; h[1] += (int32_t)c; h[0] -= (int32_t)(c<<26); c = (h[1] + (1LL<<24)) >> 25; h[2] += (int32_t)c; h[1] -= (int32_t)(c<<25); c = (h[2] + (1LL<<25)) >> 26; h[3] += (int32_t)c; h[2] -= (int32_t)(c<<26); c = (h[3] + (1LL<<24)) >> 25; h[4] += (int32_t)c; h[3] -= (int32_t)(c<<25); c = (h[4] + (1LL<<25)) >> 26; h[5] += (int32_t)c; h[4] -= (int32_t)(c<<26); c = (h[5] + (1LL<<24)) >> 25; h[6] += (int32_t)c; h[5] -= (int32_t)(c<<25); c = (h[6] + (1LL<<25)) >> 26; h[7] += (int32_t)c; h[6] -= (int32_t)(c<<26); c = (h[7] + (1LL<<24)) >> 25; h[8] += (int32_t)c; h[7] -= (int32_t)(c<<25); c = (h[8] + (1LL<<25)) >> 26; h[9] += (int32_t)c; h[8] -= (int32_t)(c<<26); c = (h[9] + (1LL<<24)) >> 25; h[0] += (int32_t)(c*19); h[9] -= (int32_t)(c<<25); c = (h[0] + (1LL<<25)) >> 26; h[1] += (int32_t)c; h[0] -= (int32_t)(c<<26); } // multiplication (ref10) static void fe_mul(fe h, const fe f, const fe g) { int64_t f0=f[0], f1=f[1], f2=f[2], f3=f[3], f4=f[4], f5=f[5], f6=f[6], f7=f[7], f8=f[8], f9=f[9]; int64_t g0=g[0], g1=g[1], g2=g[2], g3=g[3], g4=g[4], g5=g[5], g6=g[6], g7=g[7], g8=g[8], g9=g[9]; Loading @@ -81,13 +78,29 @@ static void fe_mul(fe h, const fe f, const fe g) { int64_t h8 = f0*g8 + f1*g7 + f2*g6 + f3*g5 + f4*g4 + f5*g3 + f6*g2 + f7*g1 + f8*g0 + f9*g9_19; int64_t h9 = f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0; // partial reduction + carries int64_t c; c = (h0 + (1LL<<25)) >> 26; h1 += c; h0 -= c<<26; c = (h1 + (1LL<<24)) >> 25; h2 += c; h1 -= c<<25; c = (h2 + (1LL<<25)) >> 26; h3 += c; h2 -= c<<26; c = (h3 + (1LL<<24)) >> 25; h4 += c; h3 -= c<<25; c = (h4 + (1LL<<25)) >> 26; h5 += c; h4 -= c<<26; c = (h5 + (1LL<<24)) >> 25; h6 += c; h5 -= c<<25; c = (h6 + (1LL<<25)) >> 26; h7 += c; h6 -= c<<26; c = (h7 + (1LL<<24)) >> 25; h8 += c; h7 -= c<<25; c = (h8 + (1LL<<25)) >> 26; h9 += c; h8 -= c<<26; c = (h9 + (1LL<<24)) >> 25; h0 += c*19; h9 -= c<<25; c = (h0 + (1LL<<25)) >> 26; h1 += c; h0 -= c<<26; h[0]=(int32_t)h0; h[1]=(int32_t)h1; h[2]=(int32_t)h2; h[3]=(int32_t)h3; h[4]=(int32_t)h4; h[5]=(int32_t)h5; h[6]=(int32_t)h6; h[7]=(int32_t)h7; h[8]=(int32_t)h8; h[9]=(int32_t)h9; fe_carry(h); } static void fe_sq(fe h, const fe f) { fe_mul(h,f,f); } // inversion z^(p-2) static void fe_pow22523(fe out, const fe z) { fe t0,t1,t2; fe_sq(t0,z); Loading @@ -98,39 +111,18 @@ static void fe_pow22523(fe out, const fe z) { fe_sq(t0,t0); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<5;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<20;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<100;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t0,t0); fe_sq(t0,t0); fe_sq(t1,t0); for(int i=1;i<5;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<20;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<100;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t0,t0); fe_sq(t0,t0); fe_mul(out,t0,z); } // encoding/decoding static void fe_frombytes(fe h, const uint8_t s[32]) { int64_t t0 = load32(s); int64_t t1 = load32(s+4); Loading Loading @@ -176,28 +168,51 @@ static void fe_tobytes(uint8_t s[32], fe h) { int64_t t2 = ((int64_t)h[2] >> 13) | ((int64_t)h[3] << 13); int64_t t3 = ((int64_t)h[3] >> 19) | ((int64_t)h[4] << 6); store32(s, (uint32_t)t0); store32(s+4, (uint32_t)(t0>>32)); store32(s+8, (uint32_t)t1); store32(s+12,(uint32_t)(t1>>32)); store32(s+16,(uint32_t)t2); store32(s+20,(uint32_t)(t2>>32)); store32(s+24,(uint32_t)t3); store32(s+28,(uint32_t)(t3>>32)); s[0]=(uint8_t)t0; s[1]=(uint8_t)(t0>>8); s[2]=(uint8_t)(t0>>16); s[3]=(uint8_t)(t0>>24); t0 >>= 32; s[4]=(uint8_t)t0; s[5]=(uint8_t)(t0>>8); s[6]=(uint8_t)(t0>>16); s[7]=(uint8_t)(t0>>24); s[8]=(uint8_t)t1; s[9]=(uint8_t)(t1>>8); s[10]=(uint8_t)(t1>>16); s[11]=(uint8_t)(t1>>24); t1 >>= 32; s[12]=(uint8_t)t1; s[13]=(uint8_t)(t1>>8); s[14]=(uint8_t)(t1>>16); s[15]=(uint8_t)(t1>>24); s[16]=(uint8_t)t2; s[17]=(uint8_t)(t2>>8); s[18]=(uint8_t)(t2>>16); s[19]=(uint8_t)(t2>>24); t2 >>= 32; s[20]=(uint8_t)t2; s[21]=(uint8_t)(t2>>8); s[22]=(uint8_t)(t2>>16); s[23]=(uint8_t)(t2>>24); s[24]=(uint8_t)t3; s[25]=(uint8_t)(t3>>8); s[26]=(uint8_t)(t3>>16); s[27]=(uint8_t)(t3>>24); t3 >>= 32; s[28]=(uint8_t)t3; s[29]=(uint8_t)(t3>>8); s[30]=(uint8_t)(t3>>16); s[31]=(uint8_t)(t3>>24); } static void x25519_scalarmult(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) { uint8_t e[32]; static inline void clamp_scalar(uint8_t e[32], const uint8_t scalar[32]) { memcpy(e, scalar, 32); // Clamp e[0] &= 248; e[31] &= 127; e[31] |= 64; } // A24 = 121666 (RFC7748) static void fe_mul121666(fe out, const fe in) { int64_t t; for(int i=0;i<10;i++) out[i] = in[i]; t = (int64_t)out[0] * 121666; out[0] = (int32_t)t; for(int i=1;i<10;i++) { t = (int64_t)out[i] * 121666; out[i] = (int32_t)t; } fe_carry(out); } // ---------- Montgomery ladder ---------- static void x25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) { uint8_t e[32]; clamp_scalar(e, scalar); fe x1, x2, z2, x3, z3; fe tmp0, tmp1; fe a, aa, b, bb, e1, c, d, da, cb; fe x1, x2, z2, x3, z3, tmp0, tmp1; fe_frombytes(x1, point); fe_1(x2); fe_0(z2); fe_copy(x3, x1); fe_1(z3); Loading @@ -205,37 +220,39 @@ static void x25519_scalarmult(uint8_t out[32], uint32_t swap = 0; for(int pos=254; pos>=0; --pos) { uint32_t b = (e[pos/8] >> (pos & 7)) & 1; swap ^= b; uint32_t bbit = (e[pos/8] >> (pos & 7)) & 1; swap ^= bbit; fe_cswap(x2, x3, swap); fe_cswap(z2, z3, swap); swap = b; fe_add(tmp0, x2, z2); fe_sub(tmp1, x2, z2); fe_sq(tmp0, tmp0); fe_sq(tmp1, tmp1); fe_sub(z2, tmp0, tmp1); fe_add(x3, x3, z3); fe_sub(z3, x3, z3); fe_mul(z3, z3, tmp0); fe_mul(x3, x3, tmp1); fe_add(tmp0, z3, x3); fe_sub(tmp1, z3, x3); swap = bbit; // a = x2+z2 fe_add(a, x2, z2); // b = x2-z2 fe_sub(b, x2, z2); fe_sq(aa, a); fe_sq(bb, b); // e = aa-bb fe_sub(e1, aa, bb); // c = x3+z3 fe_add(c, x3, z3); // d = x3-z3 fe_sub(d, x3, z3); fe_mul(da, d, a); fe_mul(cb, c, b); // x3 = (da+cb)^2 fe_add(tmp0, da, cb); fe_sq(x3, tmp0); fe_sq(tmp0, tmp1); fe_mul(z3, tmp0, x1); fe_mul(x2, tmp0, tmp1); // z2 = E*(AA + 121665*E) fe_mul(tmp1, z2, (fe){121665,0,0,0,0,0,0,0,0,0}); fe_add(tmp1, tmp1, tmp0); fe_mul(z2, z2, tmp1); // z3 = x1*(da-cb)^2 fe_sub(tmp1, da, cb); fe_sq(tmp1, tmp1); fe_mul(z3, tmp1, x1); // x2 = aa*bb fe_mul(x2, aa, bb); // z2 = e*(aa + A24*e) fe_mul121666(tmp0, e1); // tmp0 = A24*e fe_add(tmp0, tmp0, aa); // aa + A24*e fe_mul(z2, e1, tmp0); } fe_cswap(x2, x3, swap); Loading @@ -246,30 +263,24 @@ static void x25519_scalarmult(uint8_t out[32], fe_tobytes(out, x2); } static void x25519_scalarmult_base(uint8_t out[32], const uint8_t scalar[32]) { static const uint8_t base[32] = { 9 }; x25519_scalarmult(out, scalar, base); static bool not_all_zero(const uint8_t out[32]) { uint8_t acc = 0; for(int i=0;i<32;i++) acc |= out[i]; return acc != 0; } bool scalarmult_curve25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point_u[32]) { x25519_scalarmult(out, scalar, point_u); // reject all-zero result uint8_t acc = 0; for (int i=0;i<32;i++) acc |= out[i]; return acc != 0; x25519(out, scalar, point_u); return not_all_zero(out); } bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]) { x25519_scalarmult_base(out, scalar); uint8_t acc = 0; for (int i=0;i<32;i++) acc |= out[i]; return acc != 0; static const uint8_t base[32] = { 9 }; x25519(out, scalar, base); return not_all_zero(out); } } // namespace netplus src/crypto/curve25519.h +3 −6 Original line number Diff line number Diff line Loading @@ -3,14 +3,11 @@ namespace netplus { // out = scalar * basepoint(9) bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]); // out = scalar * point_u (point_u = 32-byte u-coordinate) bool scalarmult_curve25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point_u[32]); } // namespace netplus bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]); } // namespace netplus src/socket.h +12 −4 Original line number Diff line number Diff line Loading @@ -387,12 +387,16 @@ namespace netplus { const std::vector<uint8_t>& frag ); void _sendEncryptedRecord( netplus::ssl* cssock, void _sendTLS12Record( uint8_t recType, const std::vector<uint8_t>& content ); void _sendTLS13Record( uint8_t innerType, const std::vector<uint8_t>& plain ); void _sendHandshake( uint8_t handshakeType, const std::vector<uint8_t>& data, Loading Loading @@ -483,7 +487,6 @@ namespace netplus { bool _is_client=false; bool _handshakeStarted = false; bool _client_has_tls13_keyshare_p256 = false; std::vector<uint8_t> _tls13_client_keyshare; //debug Loading Loading @@ -544,6 +547,8 @@ namespace netplus { uint16_t _neg_version = 0x0303; // 0x0303 TLS1.2, 0x0304 TLS1.3 uint16_t _tls13_cipher = 0x1301; // TLS_AES_128_GCM_SHA256 (default for TLS1.3 path) uint8_t _tls13_selected_group=0; // TLS 1.3 ephemeral ECDHE uint8_t _tls13_cli_priv[32] = {0}; // client ephemeral scalar (BE) uint8_t _tls13_srv_priv[32] = {0}; // server ephemeral scalar (BE) Loading Loading @@ -590,7 +595,7 @@ namespace netplus { void _queueClientHello(); bool _client_has_tls13_keyshare_x25519=false; std::vector<uint8_t> _tls13_client_keyshare_x25519; // 32 bytes uint8_t _tls13_srv_priv_x25519[32]; uint8_t _tls13_srv_pub_x25519[32]; Loading Loading @@ -638,6 +643,9 @@ namespace netplus { bool _handshakeDone; bool _is_server = true; bool hasTLS13SV = false; bool hasTLS13KS = false; friend class poll; friend class event; friend class EventWorker; Loading src/ssl.cpp +488 −84 File changed.Preview size limit exceeded, changes collapsed. Show changes test/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ add_executable(tls tls.cpp) target_link_libraries(tls netplus-static) add_executable(x25519 x25519.cpp) target_link_libraries(x25519 netplus-static) add_test( NAME dest_test COMMAND des Loading Loading
src/crypto/curve25519.cpp +134 −123 Original line number Diff line number Diff line // curve25519.cpp #include "curve25519.h" #include <stdint.h> #include <string.h> namespace netplus { static inline uint32_t load32(const uint8_t *p) { return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); } // ---------- field element (10 limbs) ---------- typedef int32_t fe[10]; static inline void store32(uint8_t *p, uint32_t v) { p[0] = (uint8_t)(v); p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); static inline uint32_t load32(const uint8_t *x) { return (uint32_t)x[0] | ((uint32_t)x[1] << 8) | ((uint32_t)x[2] << 16) | ((uint32_t)x[3] << 24); } // Field element radix 2^25.5 typedef int32_t fe[10]; static void fe_0(fe h) { memset(h, 0, sizeof(fe)); } static void fe_1(fe h) { fe_0(h); h[0] = 1; } static void fe_copy(fe h, const fe f) { memcpy(h, f, sizeof(fe)); } Loading @@ -32,30 +27,32 @@ static void fe_sub(fe h, const fe f, const fe g) { } static void fe_cswap(fe f, fe g, uint32_t b) { b = -b; b = (uint32_t)(-((int32_t)b)); for (int i=0;i<10;i++) { int32_t x = b & (f[i] ^ g[i]); int32_t x = (int32_t)(b & (uint32_t)(f[i] ^ g[i])); f[i] ^= x; g[i] ^= x; } } // carry/reduce static void fe_carry(fe h) { int64_t c; c = (h[0] + ((int64_t)1<<25)) >> 26; h[1] += c; h[0] -= c<<26; c = (h[1] + ((int64_t)1<<24)) >> 25; h[2] += c; h[1] -= c<<25; c = (h[2] + ((int64_t)1<<25)) >> 26; h[3] += c; h[2] -= c<<26; c = (h[3] + ((int64_t)1<<24)) >> 25; h[4] += c; h[3] -= c<<25; c = (h[4] + ((int64_t)1<<25)) >> 26; h[5] += c; h[4] -= c<<26; c = (h[5] + ((int64_t)1<<24)) >> 25; h[6] += c; h[5] -= c<<25; c = (h[6] + ((int64_t)1<<25)) >> 26; h[7] += c; h[6] -= c<<26; c = (h[7] + ((int64_t)1<<24)) >> 25; h[8] += c; h[7] -= c<<25; c = (h[8] + ((int64_t)1<<25)) >> 26; h[9] += c; h[8] -= c<<26; c = (h[9] + ((int64_t)1<<24)) >> 25; h[0] += c*19; h[9] -= c<<25; c = (h[0] + ((int64_t)1<<25)) >> 26; h[1] += c; h[0] -= c<<26; c = (h[0] + (1LL<<25)) >> 26; h[1] += (int32_t)c; h[0] -= (int32_t)(c<<26); c = (h[1] + (1LL<<24)) >> 25; h[2] += (int32_t)c; h[1] -= (int32_t)(c<<25); c = (h[2] + (1LL<<25)) >> 26; h[3] += (int32_t)c; h[2] -= (int32_t)(c<<26); c = (h[3] + (1LL<<24)) >> 25; h[4] += (int32_t)c; h[3] -= (int32_t)(c<<25); c = (h[4] + (1LL<<25)) >> 26; h[5] += (int32_t)c; h[4] -= (int32_t)(c<<26); c = (h[5] + (1LL<<24)) >> 25; h[6] += (int32_t)c; h[5] -= (int32_t)(c<<25); c = (h[6] + (1LL<<25)) >> 26; h[7] += (int32_t)c; h[6] -= (int32_t)(c<<26); c = (h[7] + (1LL<<24)) >> 25; h[8] += (int32_t)c; h[7] -= (int32_t)(c<<25); c = (h[8] + (1LL<<25)) >> 26; h[9] += (int32_t)c; h[8] -= (int32_t)(c<<26); c = (h[9] + (1LL<<24)) >> 25; h[0] += (int32_t)(c*19); h[9] -= (int32_t)(c<<25); c = (h[0] + (1LL<<25)) >> 26; h[1] += (int32_t)c; h[0] -= (int32_t)(c<<26); } // multiplication (ref10) static void fe_mul(fe h, const fe f, const fe g) { int64_t f0=f[0], f1=f[1], f2=f[2], f3=f[3], f4=f[4], f5=f[5], f6=f[6], f7=f[7], f8=f[8], f9=f[9]; int64_t g0=g[0], g1=g[1], g2=g[2], g3=g[3], g4=g[4], g5=g[5], g6=g[6], g7=g[7], g8=g[8], g9=g[9]; Loading @@ -81,13 +78,29 @@ static void fe_mul(fe h, const fe f, const fe g) { int64_t h8 = f0*g8 + f1*g7 + f2*g6 + f3*g5 + f4*g4 + f5*g3 + f6*g2 + f7*g1 + f8*g0 + f9*g9_19; int64_t h9 = f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0; // partial reduction + carries int64_t c; c = (h0 + (1LL<<25)) >> 26; h1 += c; h0 -= c<<26; c = (h1 + (1LL<<24)) >> 25; h2 += c; h1 -= c<<25; c = (h2 + (1LL<<25)) >> 26; h3 += c; h2 -= c<<26; c = (h3 + (1LL<<24)) >> 25; h4 += c; h3 -= c<<25; c = (h4 + (1LL<<25)) >> 26; h5 += c; h4 -= c<<26; c = (h5 + (1LL<<24)) >> 25; h6 += c; h5 -= c<<25; c = (h6 + (1LL<<25)) >> 26; h7 += c; h6 -= c<<26; c = (h7 + (1LL<<24)) >> 25; h8 += c; h7 -= c<<25; c = (h8 + (1LL<<25)) >> 26; h9 += c; h8 -= c<<26; c = (h9 + (1LL<<24)) >> 25; h0 += c*19; h9 -= c<<25; c = (h0 + (1LL<<25)) >> 26; h1 += c; h0 -= c<<26; h[0]=(int32_t)h0; h[1]=(int32_t)h1; h[2]=(int32_t)h2; h[3]=(int32_t)h3; h[4]=(int32_t)h4; h[5]=(int32_t)h5; h[6]=(int32_t)h6; h[7]=(int32_t)h7; h[8]=(int32_t)h8; h[9]=(int32_t)h9; fe_carry(h); } static void fe_sq(fe h, const fe f) { fe_mul(h,f,f); } // inversion z^(p-2) static void fe_pow22523(fe out, const fe z) { fe t0,t1,t2; fe_sq(t0,z); Loading @@ -98,39 +111,18 @@ static void fe_pow22523(fe out, const fe z) { fe_sq(t0,t0); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<5;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<20;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<100;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t0,t0); fe_sq(t0,t0); fe_sq(t1,t0); for(int i=1;i<5;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<20;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<10;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t1,t0); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t1,t1,t0); fe_sq(t2,t1); for(int i=1;i<100;i++) fe_sq(t2,t2); fe_mul(t1,t2,t1); fe_sq(t1,t1); for(int i=1;i<50;i++) fe_sq(t1,t1); fe_mul(t0,t1,t0); fe_sq(t0,t0); fe_sq(t0,t0); fe_mul(out,t0,z); } // encoding/decoding static void fe_frombytes(fe h, const uint8_t s[32]) { int64_t t0 = load32(s); int64_t t1 = load32(s+4); Loading Loading @@ -176,28 +168,51 @@ static void fe_tobytes(uint8_t s[32], fe h) { int64_t t2 = ((int64_t)h[2] >> 13) | ((int64_t)h[3] << 13); int64_t t3 = ((int64_t)h[3] >> 19) | ((int64_t)h[4] << 6); store32(s, (uint32_t)t0); store32(s+4, (uint32_t)(t0>>32)); store32(s+8, (uint32_t)t1); store32(s+12,(uint32_t)(t1>>32)); store32(s+16,(uint32_t)t2); store32(s+20,(uint32_t)(t2>>32)); store32(s+24,(uint32_t)t3); store32(s+28,(uint32_t)(t3>>32)); s[0]=(uint8_t)t0; s[1]=(uint8_t)(t0>>8); s[2]=(uint8_t)(t0>>16); s[3]=(uint8_t)(t0>>24); t0 >>= 32; s[4]=(uint8_t)t0; s[5]=(uint8_t)(t0>>8); s[6]=(uint8_t)(t0>>16); s[7]=(uint8_t)(t0>>24); s[8]=(uint8_t)t1; s[9]=(uint8_t)(t1>>8); s[10]=(uint8_t)(t1>>16); s[11]=(uint8_t)(t1>>24); t1 >>= 32; s[12]=(uint8_t)t1; s[13]=(uint8_t)(t1>>8); s[14]=(uint8_t)(t1>>16); s[15]=(uint8_t)(t1>>24); s[16]=(uint8_t)t2; s[17]=(uint8_t)(t2>>8); s[18]=(uint8_t)(t2>>16); s[19]=(uint8_t)(t2>>24); t2 >>= 32; s[20]=(uint8_t)t2; s[21]=(uint8_t)(t2>>8); s[22]=(uint8_t)(t2>>16); s[23]=(uint8_t)(t2>>24); s[24]=(uint8_t)t3; s[25]=(uint8_t)(t3>>8); s[26]=(uint8_t)(t3>>16); s[27]=(uint8_t)(t3>>24); t3 >>= 32; s[28]=(uint8_t)t3; s[29]=(uint8_t)(t3>>8); s[30]=(uint8_t)(t3>>16); s[31]=(uint8_t)(t3>>24); } static void x25519_scalarmult(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) { uint8_t e[32]; static inline void clamp_scalar(uint8_t e[32], const uint8_t scalar[32]) { memcpy(e, scalar, 32); // Clamp e[0] &= 248; e[31] &= 127; e[31] |= 64; } // A24 = 121666 (RFC7748) static void fe_mul121666(fe out, const fe in) { int64_t t; for(int i=0;i<10;i++) out[i] = in[i]; t = (int64_t)out[0] * 121666; out[0] = (int32_t)t; for(int i=1;i<10;i++) { t = (int64_t)out[i] * 121666; out[i] = (int32_t)t; } fe_carry(out); } // ---------- Montgomery ladder ---------- static void x25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point[32]) { uint8_t e[32]; clamp_scalar(e, scalar); fe x1, x2, z2, x3, z3; fe tmp0, tmp1; fe a, aa, b, bb, e1, c, d, da, cb; fe x1, x2, z2, x3, z3, tmp0, tmp1; fe_frombytes(x1, point); fe_1(x2); fe_0(z2); fe_copy(x3, x1); fe_1(z3); Loading @@ -205,37 +220,39 @@ static void x25519_scalarmult(uint8_t out[32], uint32_t swap = 0; for(int pos=254; pos>=0; --pos) { uint32_t b = (e[pos/8] >> (pos & 7)) & 1; swap ^= b; uint32_t bbit = (e[pos/8] >> (pos & 7)) & 1; swap ^= bbit; fe_cswap(x2, x3, swap); fe_cswap(z2, z3, swap); swap = b; fe_add(tmp0, x2, z2); fe_sub(tmp1, x2, z2); fe_sq(tmp0, tmp0); fe_sq(tmp1, tmp1); fe_sub(z2, tmp0, tmp1); fe_add(x3, x3, z3); fe_sub(z3, x3, z3); fe_mul(z3, z3, tmp0); fe_mul(x3, x3, tmp1); fe_add(tmp0, z3, x3); fe_sub(tmp1, z3, x3); swap = bbit; // a = x2+z2 fe_add(a, x2, z2); // b = x2-z2 fe_sub(b, x2, z2); fe_sq(aa, a); fe_sq(bb, b); // e = aa-bb fe_sub(e1, aa, bb); // c = x3+z3 fe_add(c, x3, z3); // d = x3-z3 fe_sub(d, x3, z3); fe_mul(da, d, a); fe_mul(cb, c, b); // x3 = (da+cb)^2 fe_add(tmp0, da, cb); fe_sq(x3, tmp0); fe_sq(tmp0, tmp1); fe_mul(z3, tmp0, x1); fe_mul(x2, tmp0, tmp1); // z2 = E*(AA + 121665*E) fe_mul(tmp1, z2, (fe){121665,0,0,0,0,0,0,0,0,0}); fe_add(tmp1, tmp1, tmp0); fe_mul(z2, z2, tmp1); // z3 = x1*(da-cb)^2 fe_sub(tmp1, da, cb); fe_sq(tmp1, tmp1); fe_mul(z3, tmp1, x1); // x2 = aa*bb fe_mul(x2, aa, bb); // z2 = e*(aa + A24*e) fe_mul121666(tmp0, e1); // tmp0 = A24*e fe_add(tmp0, tmp0, aa); // aa + A24*e fe_mul(z2, e1, tmp0); } fe_cswap(x2, x3, swap); Loading @@ -246,30 +263,24 @@ static void x25519_scalarmult(uint8_t out[32], fe_tobytes(out, x2); } static void x25519_scalarmult_base(uint8_t out[32], const uint8_t scalar[32]) { static const uint8_t base[32] = { 9 }; x25519_scalarmult(out, scalar, base); static bool not_all_zero(const uint8_t out[32]) { uint8_t acc = 0; for(int i=0;i<32;i++) acc |= out[i]; return acc != 0; } bool scalarmult_curve25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point_u[32]) { x25519_scalarmult(out, scalar, point_u); // reject all-zero result uint8_t acc = 0; for (int i=0;i<32;i++) acc |= out[i]; return acc != 0; x25519(out, scalar, point_u); return not_all_zero(out); } bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]) { x25519_scalarmult_base(out, scalar); uint8_t acc = 0; for (int i=0;i<32;i++) acc |= out[i]; return acc != 0; static const uint8_t base[32] = { 9 }; x25519(out, scalar, base); return not_all_zero(out); } } // namespace netplus
src/crypto/curve25519.h +3 −6 Original line number Diff line number Diff line Loading @@ -3,14 +3,11 @@ namespace netplus { // out = scalar * basepoint(9) bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]); // out = scalar * point_u (point_u = 32-byte u-coordinate) bool scalarmult_curve25519(uint8_t out[32], const uint8_t scalar[32], const uint8_t point_u[32]); } // namespace netplus bool scalarmult_curve25519_base(uint8_t out[32], const uint8_t scalar[32]); } // namespace netplus
src/socket.h +12 −4 Original line number Diff line number Diff line Loading @@ -387,12 +387,16 @@ namespace netplus { const std::vector<uint8_t>& frag ); void _sendEncryptedRecord( netplus::ssl* cssock, void _sendTLS12Record( uint8_t recType, const std::vector<uint8_t>& content ); void _sendTLS13Record( uint8_t innerType, const std::vector<uint8_t>& plain ); void _sendHandshake( uint8_t handshakeType, const std::vector<uint8_t>& data, Loading Loading @@ -483,7 +487,6 @@ namespace netplus { bool _is_client=false; bool _handshakeStarted = false; bool _client_has_tls13_keyshare_p256 = false; std::vector<uint8_t> _tls13_client_keyshare; //debug Loading Loading @@ -544,6 +547,8 @@ namespace netplus { uint16_t _neg_version = 0x0303; // 0x0303 TLS1.2, 0x0304 TLS1.3 uint16_t _tls13_cipher = 0x1301; // TLS_AES_128_GCM_SHA256 (default for TLS1.3 path) uint8_t _tls13_selected_group=0; // TLS 1.3 ephemeral ECDHE uint8_t _tls13_cli_priv[32] = {0}; // client ephemeral scalar (BE) uint8_t _tls13_srv_priv[32] = {0}; // server ephemeral scalar (BE) Loading Loading @@ -590,7 +595,7 @@ namespace netplus { void _queueClientHello(); bool _client_has_tls13_keyshare_x25519=false; std::vector<uint8_t> _tls13_client_keyshare_x25519; // 32 bytes uint8_t _tls13_srv_priv_x25519[32]; uint8_t _tls13_srv_pub_x25519[32]; Loading Loading @@ -638,6 +643,9 @@ namespace netplus { bool _handshakeDone; bool _is_server = true; bool hasTLS13SV = false; bool hasTLS13KS = false; friend class poll; friend class event; friend class EventWorker; Loading
test/CMakeLists.txt +5 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ add_executable(tls tls.cpp) target_link_libraries(tls netplus-static) add_executable(x25519 x25519.cpp) target_link_libraries(x25519 netplus-static) add_test( NAME dest_test COMMAND des Loading