mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
pre-calculate ephemeral keys for x25519
This commit is contained in:
parent
df9965e129
commit
1f31fdc257
|
@ -83,7 +83,7 @@ namespace transport
|
|||
|
||||
void NTCP2Establisher::KDF1Alice ()
|
||||
{
|
||||
KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ());
|
||||
KeyDerivationFunction1 (m_RemoteStaticKey, *m_EphemeralKeys, m_RemoteStaticKey, GetPub ());
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KDF1Bob ()
|
||||
|
@ -102,7 +102,7 @@ namespace transport
|
|||
|
||||
// x25519 between remote pub and ephemaral priv
|
||||
uint8_t inputKeyMaterial[32];
|
||||
m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial);
|
||||
m_EphemeralKeys->Agree (GetRemotePub (), inputKeyMaterial);
|
||||
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
@ -127,13 +127,13 @@ namespace transport
|
|||
void NTCP2Establisher::KDF3Bob ()
|
||||
{
|
||||
uint8_t inputKeyMaterial[32];
|
||||
m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial);
|
||||
m_EphemeralKeys->Agree (m_RemoteStaticKey, inputKeyMaterial);
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::CreateEphemeralKey ()
|
||||
{
|
||||
m_EphemeralKeys.GenerateKeys ();
|
||||
m_EphemeralKeys = i2p::transport::transports.GetNextX25519KeysPair ();
|
||||
}
|
||||
|
||||
void NTCP2Establisher::CreateSessionRequestMessage ()
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace transport
|
|||
NTCP2Establisher ();
|
||||
~NTCP2Establisher ();
|
||||
|
||||
const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); };
|
||||
const uint8_t * GetPub () const { return m_EphemeralKeys->GetPublicKey (); };
|
||||
const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob
|
||||
uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set
|
||||
|
||||
|
@ -110,7 +110,7 @@ namespace transport
|
|||
bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce);
|
||||
bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf);
|
||||
|
||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||
std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
|
||||
uint8_t m_RemoteEphemeralPublicKey[32]; // x25519
|
||||
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[64] /* [ck, k]*/;
|
||||
i2p::data::IdentHash m_RemoteIdentHash;
|
||||
|
|
|
@ -21,23 +21,27 @@ namespace i2p
|
|||
{
|
||||
namespace transport
|
||||
{
|
||||
DHKeysPairSupplier::DHKeysPairSupplier (int size):
|
||||
template<typename Keys>
|
||||
EphemeralKeysSupplier<Keys>::EphemeralKeysSupplier (int size):
|
||||
m_QueueSize (size), m_IsRunning (false), m_Thread (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DHKeysPairSupplier::~DHKeysPairSupplier ()
|
||||
template<typename Keys>
|
||||
EphemeralKeysSupplier<Keys>::~EphemeralKeysSupplier ()
|
||||
{
|
||||
Stop ();
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::Start ()
|
||||
template<typename Keys>
|
||||
void EphemeralKeysSupplier<Keys>::Start ()
|
||||
{
|
||||
m_IsRunning = true;
|
||||
m_Thread = new std::thread (std::bind (&DHKeysPairSupplier::Run, this));
|
||||
m_Thread = new std::thread (std::bind (&EphemeralKeysSupplier<Keys>::Run, this));
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::Stop ()
|
||||
template<typename Keys>
|
||||
void EphemeralKeysSupplier<Keys>::Stop ()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
|
@ -52,19 +56,20 @@ namespace transport
|
|||
}
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::Run ()
|
||||
template<typename Keys>
|
||||
void EphemeralKeysSupplier<Keys>::Run ()
|
||||
{
|
||||
while (m_IsRunning)
|
||||
{
|
||||
int num, total = 0;
|
||||
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 10)
|
||||
{
|
||||
CreateDHKeysPairs (num);
|
||||
CreateEphemeralKeys (num);
|
||||
total += num;
|
||||
}
|
||||
if (total >= 10)
|
||||
{
|
||||
LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time");
|
||||
LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time");
|
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break
|
||||
}
|
||||
else
|
||||
|
@ -76,13 +81,14 @@ namespace transport
|
|||
}
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::CreateDHKeysPairs (int num)
|
||||
template<typename Keys>
|
||||
void EphemeralKeysSupplier<Keys>::CreateEphemeralKeys (int num)
|
||||
{
|
||||
if (num > 0)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
|
||||
auto pair = std::make_shared<Keys> ();
|
||||
pair->GenerateKeys ();
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
m_Queue.push (pair);
|
||||
|
@ -90,7 +96,8 @@ namespace transport
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::crypto::DHKeys> DHKeysPairSupplier::Acquire ()
|
||||
template<typename Keys>
|
||||
std::shared_ptr<Keys> EphemeralKeysSupplier<Keys>::Acquire ()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
|
@ -103,12 +110,13 @@ namespace transport
|
|||
}
|
||||
}
|
||||
// queue is empty, create new
|
||||
auto pair = std::make_shared<i2p::crypto::DHKeys> ();
|
||||
auto pair = std::make_shared<Keys> ();
|
||||
pair->GenerateKeys ();
|
||||
return pair;
|
||||
}
|
||||
|
||||
void DHKeysPairSupplier::Return (std::shared_ptr<i2p::crypto::DHKeys> pair)
|
||||
template<typename Keys>
|
||||
void EphemeralKeysSupplier<Keys>::Return (std::shared_ptr<Keys> pair)
|
||||
{
|
||||
if (pair)
|
||||
{
|
||||
|
@ -126,7 +134,7 @@ namespace transport
|
|||
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_Thread (nullptr), m_Service (nullptr),
|
||||
m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
|
||||
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_NTCP2Server (nullptr),
|
||||
m_DHKeysPairSupplier (5), // 5 pre-generated keys
|
||||
m_DHKeysPairSupplier (5), m_X25519KeysPairSupplier (5), // 5 pre-generated keys
|
||||
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0),
|
||||
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0),
|
||||
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0),
|
||||
|
@ -158,6 +166,7 @@ namespace transport
|
|||
|
||||
i2p::config::GetOption("nat", m_IsNAT);
|
||||
m_DHKeysPairSupplier.Start ();
|
||||
m_X25519KeysPairSupplier.Start ();
|
||||
m_IsRunning = true;
|
||||
m_Thread = new std::thread (std::bind (&Transports::Run, this));
|
||||
std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy);
|
||||
|
@ -312,6 +321,7 @@ namespace transport
|
|||
}
|
||||
|
||||
m_DHKeysPairSupplier.Stop ();
|
||||
m_X25519KeysPairSupplier.Stop ();
|
||||
m_IsRunning = false;
|
||||
if (m_Service) m_Service->stop ();
|
||||
if (m_Thread)
|
||||
|
@ -630,6 +640,16 @@ namespace transport
|
|||
m_DHKeysPairSupplier.Return (pair);
|
||||
}
|
||||
|
||||
std::shared_ptr<i2p::crypto::X25519Keys> Transports::GetNextX25519KeysPair ()
|
||||
{
|
||||
return m_X25519KeysPairSupplier.Acquire ();
|
||||
}
|
||||
|
||||
void Transports::ReuseX25519KeysPair (std::shared_ptr<i2p::crypto::X25519Keys> pair)
|
||||
{
|
||||
m_X25519KeysPairSupplier.Return (pair);
|
||||
}
|
||||
|
||||
void Transports::PeerConnected (std::shared_ptr<TransportSession> session)
|
||||
{
|
||||
m_Service->post([session, this]()
|
||||
|
|
|
@ -32,32 +32,36 @@ namespace i2p
|
|||
{
|
||||
namespace transport
|
||||
{
|
||||
class DHKeysPairSupplier
|
||||
template<typename Keys>
|
||||
class EphemeralKeysSupplier
|
||||
{
|
||||
// called from this file only, so implementation is in Transports.cpp
|
||||
public:
|
||||
|
||||
DHKeysPairSupplier (int size);
|
||||
~DHKeysPairSupplier ();
|
||||
EphemeralKeysSupplier (int size);
|
||||
~EphemeralKeysSupplier ();
|
||||
void Start ();
|
||||
void Stop ();
|
||||
std::shared_ptr<i2p::crypto::DHKeys> Acquire ();
|
||||
void Return (std::shared_ptr<i2p::crypto::DHKeys> pair);
|
||||
std::shared_ptr<Keys> Acquire ();
|
||||
void Return (std::shared_ptr<Keys> pair);
|
||||
|
||||
private:
|
||||
|
||||
void Run ();
|
||||
void CreateDHKeysPairs (int num);
|
||||
void CreateEphemeralKeys (int num);
|
||||
|
||||
private:
|
||||
|
||||
const int m_QueueSize;
|
||||
std::queue<std::shared_ptr<i2p::crypto::DHKeys> > m_Queue;
|
||||
std::queue<std::shared_ptr<Keys> > m_Queue;
|
||||
|
||||
bool m_IsRunning;
|
||||
std::thread * m_Thread;
|
||||
std::condition_variable m_Acquired;
|
||||
std::mutex m_AcquiredMutex;
|
||||
};
|
||||
typedef EphemeralKeysSupplier<i2p::crypto::DHKeys> DHKeysPairSupplier;
|
||||
typedef EphemeralKeysSupplier<i2p::crypto::X25519Keys> X25519KeysPairSupplier;
|
||||
|
||||
struct Peer
|
||||
{
|
||||
|
@ -97,6 +101,8 @@ namespace transport
|
|||
boost::asio::io_service& GetService () { return *m_Service; };
|
||||
std::shared_ptr<i2p::crypto::DHKeys> GetNextDHKeysPair ();
|
||||
void ReuseDHKeysPair (std::shared_ptr<i2p::crypto::DHKeys> pair);
|
||||
std::shared_ptr<i2p::crypto::X25519Keys> GetNextX25519KeysPair ();
|
||||
void ReuseX25519KeysPair (std::shared_ptr<i2p::crypto::X25519Keys> pair);
|
||||
|
||||
void SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr<i2p::I2NPMessage> msg);
|
||||
void SendMessages (const i2p::data::IdentHash& ident, const std::vector<std::shared_ptr<i2p::I2NPMessage> >& msgs);
|
||||
|
@ -160,6 +166,7 @@ namespace transport
|
|||
std::unordered_map<i2p::data::IdentHash, Peer> m_Peers;
|
||||
|
||||
DHKeysPairSupplier m_DHKeysPairSupplier;
|
||||
X25519KeysPairSupplier m_X25519KeysPairSupplier;
|
||||
|
||||
std::atomic<uint64_t> m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes;
|
||||
uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; // bytes per second
|
||||
|
|
Loading…
Reference in a new issue