Commit 49540636 authored by jan.koester's avatar jan.koester
Browse files

test

parent c65bb0c6
Loading
Loading
Loading
Loading
+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)); }
@@ -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];
@@ -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);
@@ -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);
@@ -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);
@@ -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);
@@ -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
+3 −6
Original line number Diff line number Diff line
@@ -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
+12 −4
Original line number Diff line number Diff line
@@ -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,
@@ -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
@@ -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)
@@ -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];
@@ -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;
+488 −84

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -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