Commit 5673f282 authored by jan.koester's avatar jan.koester
Browse files

test

parent 362efe61
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
@@ -26,5 +27,8 @@ Extra Arguments=
Install Directory=/usr/local
Runtime=Host-System

[MakeBuilder]
Make Binary=ninja

[Project]
VersionControlSupport=kdevgit
+71 −45
Original line number Diff line number Diff line
@@ -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;
}

@@ -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];
@@ -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;
}

@@ -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];

@@ -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);
@@ -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,
@@ -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
@@ -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;
@@ -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;
}

+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,
@@ -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
+0 −15
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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++;