i2pdtunnelwizard/x25519/x25519cpp.cpp

130 lines
2.8 KiB
C++

// acetone, 2025
// I hate copyright of any kind. This is a public domain.
// Original source: http://git.community.i2p/acetone/i2pdtunnelwizard
#include "x25519cpp.h"
#include "cbackend/x25519.h"
#include "../codec/base64_i2p.hpp"
#include <random>
#include <cstring>
X25519Keys::X25519Keys(const std::array<uint8_t, 32> &sk)
{
setSecretKey(sk);
}
void X25519Keys::generateKeys ()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(0, 255);
for (size_t i = 0; i < m_secretKey.size(); ++i)
{
m_secretKey[i] = dist(gen);
}
x25519_base(m_publicKey.data(), m_secretKey.data());
}
const std::shared_ptr<std::array<uint8_t, 32>> X25519Keys::agree(const std::array<uint8_t, 32> &pub) const
{
auto shared = std::make_shared<std::array<uint8_t, 32>>();
x25519(shared->data(), m_secretKey.data(), pub.data());
return shared;
}
const std::shared_ptr<std::array<uint8_t, 32>> X25519Keys::agree(const std::string &pkey) const
{
if (pkey.size() != 43)
{
return nullptr;
}
std::vector<uint8_t> decoded;
try {
cppcodec_samty::base64_i2p::decode(pkey);
} catch (...)
{
return nullptr;
}
if (decoded.size() != 32)
{
return nullptr;
}
return agree(decoded.data(), decoded.size());
}
const std::shared_ptr<std::array<uint8_t, 32>> X25519Keys::agree(const uint8_t *pkey, size_t size) const
{
if (size != 32)
{
return nullptr;
}
std::array<uint8_t, 32> key;
for (int i = 0; i < 32; i++)
{
key[i] = pkey[i];
}
return agree(key);
}
bool X25519Keys::setSecretKey (const uint8_t * sec, bool calculatePublic)
{
for (int i = 0; i < X25519_KEY_LEN; i++)
{
m_secretKey[i] = sec[i];
}
if (calculatePublic)
{
x25519_base(m_publicKey.data(), m_secretKey.data());
}
return true;
}
bool X25519Keys::setSecretKey(const std::string &sec, bool calculatePublic)
{
if (sec.size() != 43)
{
return false;
}
std::vector<uint8_t> decoded;
try {
cppcodec_samty::base64_i2p::decode(sec);
} catch (...)
{
return false;
}
return setSecretKey(decoded, calculatePublic);
}
bool X25519Keys::setSecretKey(const std::vector<uint8_t>& sec, bool calculatePublic)
{
if (sec.size() != 32)
{
return false;
}
return setSecretKey(sec.data(), calculatePublic);
}
bool X25519Keys::setSecretKey(const std::array<uint8_t, 32> &sec, bool calculatePublic)
{
return setSecretKey(sec.data(), calculatePublic);
}
std::string X25519Keys::getPublicKeyBase64() const
{
return cppcodec_samty::base64_i2p::encode(m_publicKey.data(), m_publicKey.size());
}
std::string X25519Keys::getSecretKeyBase64() const
{
return cppcodec_samty::base64_i2p::encode(m_secretKey.data(), m_secretKey.size());
}