EdDSA speed improvement

This commit is contained in:
orignal 2015-11-04 13:48:30 -05:00
parent 4dea2ef1a4
commit 962261fee7
3 changed files with 37 additions and 13 deletions

View File

@ -30,7 +30,11 @@ namespace i2p
void RouterContext::CreateNewRouter () 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); 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 (); SaveKeys ();
NewRouterInfo (); NewRouterInfo ();
} }

View File

@ -39,7 +39,7 @@ namespace crypto
BN_set_word (tmp, 121666); BN_set_word (tmp, 121666);
Inv (tmp, ctx); Inv (tmp, ctx);
BN_set_word (d, 121665); BN_set_word (d, 121665);
BN_set_negative (d, -1); BN_set_negative (d, 1);
BN_mul (d, d, tmp, ctx); BN_mul (d, d, tmp, ctx);
// 2^((q-1)/4) // 2^((q-1)/4)
@ -63,10 +63,14 @@ namespace crypto
BN_free (two); BN_free (two);
BN_free (tmp); BN_free (tmp);
// precalculate Bi // precalculate Bi16 table
Bi[0] = { BN_dup (Bx), BN_dup (By) }; Bi16[0][0] = { BN_dup (Bx), BN_dup (By) };
for (int i = 1; i < 256; i++) for (int i = 0; i < 64; i++)
Bi[i] = Double (Bi[i-1], ctx); {
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); BN_CTX_free (ctx);
} }
@ -101,8 +105,13 @@ namespace crypto
{ {
BIGNUM * h = DecodeBN (digest, 64); BIGNUM * h = DecodeBN (digest, 64);
// signature 0..31 - R, 32..63 - S // signature 0..31 - R, 32..63 - S
bool passed = MulB (signature + EDDSA25519_SIGNATURE_LENGTH/2, ctx) /*S*/ == // B*S = R + PK*h => R = B*S - PK*h
Sum (DecodePoint (signature, ctx) /*R*/, Mul (publicKey, h, ctx), ctx); // 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); BN_free (h);
if (!passed) if (!passed)
LogPrint (eLogError, "25519 signature verification failed"); LogPrint (eLogError, "25519 signature verification failed");
@ -243,9 +252,12 @@ namespace crypto
EDDSAPoint res {zero, one}; EDDSAPoint res {zero, one};
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
for (int j = 0; j < 8; j++) uint8_t x = e[i] & 0x0F; // 4 low bits
if (e[i] & (1 << j)) // from lowest to highest bit if (x > 0)
res = Sum (res, Bi[i*8 + j], ctx); 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; return res;
} }
@ -365,7 +377,7 @@ namespace crypto
// transient values // transient values
BIGNUM * q_2; // q-2 BIGNUM * q_2; // q-2
BIGNUM * two_252_2; // 2^252-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<Ed25519> g_Ed25519; static std::unique_ptr<Ed25519> g_Ed25519;

View File

@ -390,6 +390,14 @@ namespace crypto
{ {
return !BN_cmp (x, other.x) && !BN_cmp (y, other.y); 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; const size_t EDDSA25519_PUBLIC_KEY_LENGTH = 32;