diff --git a/Crypto.cpp b/Crypto.cpp
index b42dafa6..0ec0f020 100644
--- a/Crypto.cpp
+++ b/Crypto.cpp
@@ -146,6 +146,10 @@ namespace crypto
}
// DH/ElGamal
+
+ const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226;
+ const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048;
+
#define elgp GetCryptoConstants ().elgp
#define elgg GetCryptoConstants ().elgg
@@ -169,6 +173,10 @@ namespace crypto
{
if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; };
if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; };
+#if !defined(__x86_64__) // use short exponent for non x64
+ m_DH->priv_key = BN_new ();
+ BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
+#endif
DH_generate_key (m_DH);
if (priv) bn2buf (m_DH->priv_key, priv, 256);
if (pub) bn2buf (m_DH->pub_key, pub, 256);
@@ -201,9 +209,9 @@ namespace crypto
// select random k
BIGNUM * k = BN_new ();
#if defined(__x86_64__)
- BN_rand (k, 2048, -1, 1); // full exponent for x64
+ BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64
#else
- BN_rand (k, 226, -1, 1); // short exponent of 226 bits
+ BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits
#endif
// caulculate a
a = BN_new ();
@@ -282,6 +290,14 @@ namespace crypto
{
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
RAND_bytes (priv, 256);
+#else
+ // lower 226 bits (28 bytes and 2 bits) only. short exponent
+ auto numBytes = (ELGAMAL_SHORT_EXPONENT_NUM_BITS)/8 + 1; // 29
+ auto numZeroBytes = 256 - numBytes;
+ RAND_bytes (priv + numZeroBytes, numBytes);
+ memset (priv, 0, numZeroBytes);
+ priv[numZeroBytes] &= 0x03;
+#endif
BN_CTX * ctx = BN_CTX_new ();
BIGNUM * p = BN_new ();
BN_bin2bn (priv, 256, p);
@@ -289,11 +305,6 @@ namespace crypto
bn2buf (p, pub, 256);
BN_free (p);
BN_CTX_free (ctx);
-#else
- DHKeys dh;
- dh.GenerateKeys (priv, pub);
-
-#endif
}
// HMAC
diff --git a/HTTPServer.cpp b/HTTPServer.cpp
index 8db9d330..06fabc31 100644
--- a/HTTPServer.cpp
+++ b/HTTPServer.cpp
@@ -777,20 +777,20 @@ namespace util
s << "Client Tunnels:
\r\n
\r\n";
for (auto& it: i2p::client::context.GetClientTunnels ())
{
- s << it.second->GetName () << " ⇐ ";
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "";
+ s << it.second->GetName () << " ⇐ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
- s << "
\r\n"<< std::endl;
+ s << "
\r\n"<< std::endl;
}
s << "
\r\nServer Tunnels:
\r\n
\r\n";
for (auto& it: i2p::client::context.GetServerTunnels ())
{
- s << it.second->GetName () << " ⇒ ";
auto& ident = it.second->GetLocalDestination ()->GetIdentHash();
s << "";
+ s << it.second->GetName () << " ⇒ ";
s << i2p::client::context.GetAddressBook ().ToAddress(ident);
s << ":" << it.second->GetLocalPort ();
s << "
\r\n"<< std::endl;
diff --git a/Identity.cpp b/Identity.cpp
index 0ca9567a..f221dd04 100644
--- a/Identity.cpp
+++ b/Identity.cpp
@@ -311,18 +311,18 @@ namespace data
switch (keyType)
{
case SIGNING_KEY_TYPE_DSA_SHA1:
- m_Verifier.reset (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey));
+ UpdateVerifier (new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey));
break;
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
{
size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
- m_Verifier.reset (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding));
+ UpdateVerifier (new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA384_P384:
{
size_t padding = 128 - i2p::crypto::ECDSAP384_KEY_LENGTH; // 32 = 128 - 96
- m_Verifier.reset (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding));
+ UpdateVerifier (new i2p::crypto::ECDSAP384Verifier (m_StandardIdentity.signingKey + padding));
break;
}
case SIGNING_KEY_TYPE_ECDSA_SHA512_P521:
@@ -331,7 +331,7 @@ namespace data
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::ECDSAP521_KEY_LENGTH - 128; // 4 = 132- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
- m_Verifier.reset (new i2p::crypto::ECDSAP521Verifier (signingKey));
+ UpdateVerifier (new i2p::crypto::ECDSAP521Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
@@ -340,7 +340,7 @@ namespace data
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
- m_Verifier.reset (new i2p::crypto:: RSASHA2562048Verifier (signingKey));
+ UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
@@ -349,7 +349,7 @@ namespace data
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
- m_Verifier.reset (new i2p::crypto:: RSASHA3843072Verifier (signingKey));
+ UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
@@ -358,20 +358,28 @@ namespace data
memcpy (signingKey, m_StandardIdentity.signingKey, 128);
size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128
memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types
- m_Verifier.reset (new i2p::crypto:: RSASHA5124096Verifier (signingKey));
+ UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey));
break;
}
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
{
size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32
- m_Verifier.reset (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding));
+ UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding));
break;
}
default:
LogPrint (eLogError, "Identity: Signing key type ", (int)keyType, " is not supported");
}
}
-
+
+ void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
+ {
+ if (!m_Verifier || !verifier)
+ m_Verifier.reset (verifier);
+ else
+ delete verifier;
+ }
+
void IdentityEx::DropVerifier () const
{
// TODO: potential race condition with Verify
diff --git a/Identity.h b/Identity.h
index 27da190d..d8abd6f4 100644
--- a/Identity.h
+++ b/Identity.h
@@ -95,6 +95,7 @@ namespace data
private:
void CreateVerifier () const;
+ void UpdateVerifier (i2p::crypto::Verifier * verifier) const;
private: