From 962261fee75abbdf4bfd7af1cf945e152e539432 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 4 Nov 2015 13:48:30 -0500 Subject: [PATCH] EdDSA speed improvement --- RouterContext.cpp | 4 ++++ Signature.cpp | 34 +++++++++++++++++++++++----------- Signature.h | 12 ++++++++++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/RouterContext.cpp b/RouterContext.cpp index 148b87e0..6629f774 100644 --- a/RouterContext.cpp +++ b/RouterContext.cpp @@ -30,7 +30,11 @@ namespace i2p void RouterContext::CreateNewRouter () { +#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER) m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519); +#else + m_Keys = i2p::data::PrivateKeys::CreateRandomKeys (i2p::data::SIGNING_KEY_TYPE_DSA_SHA1); +#endif SaveKeys (); NewRouterInfo (); } diff --git a/Signature.cpp b/Signature.cpp index 40947aa6..a14099ac 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -39,7 +39,7 @@ namespace crypto BN_set_word (tmp, 121666); Inv (tmp, ctx); BN_set_word (d, 121665); - BN_set_negative (d, -1); + BN_set_negative (d, 1); BN_mul (d, d, tmp, ctx); // 2^((q-1)/4) @@ -63,10 +63,14 @@ namespace crypto BN_free (two); BN_free (tmp); - // precalculate Bi - Bi[0] = { BN_dup (Bx), BN_dup (By) }; - for (int i = 1; i < 256; i++) - Bi[i] = Double (Bi[i-1], ctx); + // precalculate Bi16 table + Bi16[0][0] = { BN_dup (Bx), BN_dup (By) }; + for (int i = 0; i < 64; i++) + { + if (i) Bi16[i][0] = Sum (Bi16[i-1][14], Bi16[i-1][0], ctx); + for (int j = 1; j < 15; j++) + Bi16[i][j] = Sum (Bi16[i][j-1], Bi16[i][0], ctx); // (16+j+1)^i*B + } BN_CTX_free (ctx); } @@ -101,8 +105,13 @@ namespace crypto { BIGNUM * h = DecodeBN (digest, 64); // signature 0..31 - R, 32..63 - S - bool passed = MulB (signature + EDDSA25519_SIGNATURE_LENGTH/2, ctx) /*S*/ == - Sum (DecodePoint (signature, ctx) /*R*/, Mul (publicKey, h, ctx), ctx); + // B*S = R + PK*h => R = B*S - PK*h + // we don't decode R, but encode (B*S - PK*h) + auto Bs = MulB (signature + EDDSA25519_SIGNATURE_LENGTH/2, ctx); // B*S; + auto PKh = Mul (publicKey, h, ctx); // PK*h + uint8_t diff[32]; + EncodePoint (Sum (Bs, -PKh, ctx), diff); // Bs - PKh encoded + bool passed = !memcmp (signature, diff, 32); // R BN_free (h); if (!passed) LogPrint (eLogError, "25519 signature verification failed"); @@ -243,9 +252,12 @@ namespace crypto EDDSAPoint res {zero, one}; for (int i = 0; i < 32; i++) { - for (int j = 0; j < 8; j++) - if (e[i] & (1 << j)) // from lowest to highest bit - res = Sum (res, Bi[i*8 + j], ctx); + uint8_t x = e[i] & 0x0F; // 4 low bits + if (x > 0) + res = Sum (res, Bi16[i*2][x-1], ctx); + x = e[i] >> 4; // 4 high bits + if (x > 0) + res = Sum (res, Bi16[i*2+1][x-1], ctx); } return res; } @@ -365,7 +377,7 @@ namespace crypto // transient values BIGNUM * q_2; // q-2 BIGNUM * two_252_2; // 2^252-2 - EDDSAPoint Bi[256]; // m_Bi[i] = 2^i*B for i-th bit + EDDSAPoint Bi16[64][15]; // per 4-bits, Bi16[i][j] = (16+j+1)^i*B, we don't store zeroes }; static std::unique_ptr g_Ed25519; diff --git a/Signature.h b/Signature.h index 423559a3..c4ccf8fc 100644 --- a/Signature.h +++ b/Signature.h @@ -377,7 +377,7 @@ namespace crypto EDDSAPoint (BIGNUM * x1, BIGNUM * y1): x(x1), y(y1) {}; ~EDDSAPoint () { BN_free (x); BN_free (y); }; - EDDSAPoint& operator= (EDDSAPoint&& other) + EDDSAPoint& operator=(EDDSAPoint&& other) { if (x) BN_free (x); if (y) BN_free (y); @@ -386,10 +386,18 @@ namespace crypto return *this; } - bool operator== (const EDDSAPoint& other) const + bool operator==(const EDDSAPoint& other) const { return !BN_cmp (x, other.x) && !BN_cmp (y, other.y); } + + EDDSAPoint operator-() const + { + BIGNUM * x1 = NULL, * y1 = NULL; + if (x) { x1 = BN_dup (x); BN_set_negative (x1, !BN_is_negative (x)); }; + if (y) y1 = BN_dup (y); + return EDDSAPoint {x1, y1}; + } }; const size_t EDDSA25519_PUBLIC_KEY_LENGTH = 32;