130 lines
2.8 KiB
C++
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());
|
|
}
|
|
|