mirror of https://github.com/oxen-io/lokinet
does not work
This commit is contained in:
parent
99eb7726ff
commit
0f13591802
|
@ -42,8 +42,8 @@ else()
|
|||
target_link_directories(${EXE} PRIVATE /usr/local/lib)
|
||||
target_link_directories(${CTL} PRIVATE /usr/local/lib)
|
||||
endif()
|
||||
target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS})
|
||||
target_link_libraries(${CTL} PUBLIC ${EXE_LIBS} ${LIBS})
|
||||
target_link_libraries(${EXE} PUBLIC ${EXE_LIBS} ${LIBS} ${CRYPTOGRAPHY_LIB})
|
||||
target_link_libraries(${CTL} PUBLIC ${EXE_LIBS} ${LIBS} ${CRYPTOGRAPHY_LIB})
|
||||
|
||||
if(CURL_FOUND)
|
||||
target_include_directories(${CTL} PRIVATE ${CURL_INCLUDE_DIRS})
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
#include <sodium/crypto_generichash.h>
|
||||
#include <sodium/crypto_sign.h>
|
||||
#include <sodium/crypto_scalarmult.h>
|
||||
#include <sodium/crypto_scalarmult_ed25519.h>
|
||||
#include <sodium/crypto_scalarmult_ristretto255.h>
|
||||
#include <sodium/crypto_stream_xchacha20.h>
|
||||
#include <sodium/crypto_core_ed25519.h>
|
||||
#include <sodium/crypto_core_ristretto255.h>
|
||||
#include <util/mem.hpp>
|
||||
#include <util/endian.hpp>
|
||||
#include <cassert>
|
||||
|
@ -181,6 +184,33 @@ namespace llarp
|
|||
!= -1;
|
||||
}
|
||||
|
||||
/// clamp a 32 byte ec point
|
||||
static void
|
||||
clamp_ed25519(byte_t *out)
|
||||
{
|
||||
out[0] &= 248;
|
||||
out[31] &= 127;
|
||||
out[31] |= 64;
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
static K
|
||||
clamp(const K &p)
|
||||
{
|
||||
K out = p;
|
||||
clamp_ed25519(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
static bool
|
||||
is_clamped(const K &key)
|
||||
{
|
||||
K other(key);
|
||||
clamp_ed25519(other.data());
|
||||
return other == key;
|
||||
}
|
||||
|
||||
template < typename K >
|
||||
static bool
|
||||
make_scalar(byte_t *out, const K &k, uint64_t i)
|
||||
|
@ -194,48 +224,58 @@ namespace llarp
|
|||
if(not hash(h.data(), llarp_buffer_t(buf)))
|
||||
return false;
|
||||
// return make_point(n)
|
||||
return crypto_core_ed25519_from_hash(out, h.data()) != -1;
|
||||
return crypto_core_ed25519_from_uniform(out, h.data()) != -1;
|
||||
}
|
||||
|
||||
static AlignedBuffer< 32 > zero;
|
||||
|
||||
bool
|
||||
CryptoLibSodium::derive_subkey(PubKey &out_k, const PubKey &in_k,
|
||||
CryptoLibSodium::derive_subkey(PubKey &out_key, const PubKey &root_key,
|
||||
uint64_t key_n)
|
||||
{
|
||||
// scalar p
|
||||
AlignedBuffer< 32 > p;
|
||||
// p = H( i || in_k )
|
||||
if(not make_scalar(p.data(), in_k, key_n))
|
||||
if(not make_scalar(p.data(), root_key, key_n))
|
||||
return false;
|
||||
// out_k = in_k * p % N
|
||||
crypto_core_ed25519_scalar_mul(out_k.data(), in_k.data(), p.data());
|
||||
crypto_core_ed25519_scalar_mul(out_key.data(), root_key.data(), p.data());
|
||||
LogInfo("derive_subkey() scalar = ", p, " root_key = ", root_key,
|
||||
" derived_key = ", out_key);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CryptoLibSodium::derive_subkey_secret(SecretKey &out_k,
|
||||
const SecretKey &in_k, uint64_t key_n)
|
||||
CryptoLibSodium::derive_subkey_secret(SecretKey &out_key,
|
||||
const SecretKey &in_key,
|
||||
uint64_t key_n)
|
||||
{
|
||||
const PubKey root_key = in_key.toPublic();
|
||||
// scalar p
|
||||
AlignedBuffer< 32 > p;
|
||||
// p = H( i || in_k.pub)
|
||||
if(not make_scalar(p.data(), in_k.toPublic(), key_n))
|
||||
// p = H( i || in_key.pub)
|
||||
if(not make_scalar(p.data(), root_key, key_n))
|
||||
{
|
||||
LogError("cannot make scalar");
|
||||
return false;
|
||||
// out_k = in_n * p % N
|
||||
crypto_core_ed25519_scalar_mul(out_k.data(), in_k.data(), p.data());
|
||||
// recalculate out_K public component
|
||||
return out_k.Recalculate();
|
||||
}
|
||||
// a * p * basepoint
|
||||
crypto_core_ed25519_scalar_mul(out_key.data(), in_key.data(), p.data());
|
||||
if(not out_key.Recalculate())
|
||||
return false;
|
||||
LogInfo("derive_subkey_secret() scalar = ", p, " root_key = ", root_key,
|
||||
" derived_key = ", out_key.toPublic(),
|
||||
" full_derived_key = ", out_key.ToHex());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CryptoLibSodium::seed_to_secretkey(llarp::SecretKey &secret,
|
||||
const llarp::IdentitySecret &seed)
|
||||
{
|
||||
PubKey pk;
|
||||
return crypto_sign_ed25519_seed_keypair(pk.data(), secret.data(),
|
||||
return crypto_sign_ed25519_seed_keypair(secret.data() + 32, secret.data(),
|
||||
seed.data())
|
||||
!= -1;
|
||||
}
|
||||
|
||||
void
|
||||
CryptoLibSodium::randomize(const llarp_buffer_t &buff)
|
||||
{
|
||||
|
@ -258,6 +298,8 @@ namespace llarp
|
|||
assert(pk == sk_pk);
|
||||
(void)result;
|
||||
(void)sk_pk;
|
||||
|
||||
// encryption_keygen(keys);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <sodium/crypto_sign.h>
|
||||
#include <sodium/crypto_sign_ed25519.h>
|
||||
#include <sodium/crypto_scalarmult_ed25519.h>
|
||||
|
||||
namespace llarp
|
||||
{
|
||||
|
@ -57,10 +58,7 @@ namespace llarp
|
|||
bool
|
||||
SecretKey::Recalculate()
|
||||
{
|
||||
AlignedBuffer< 32 > seed;
|
||||
if(crypto_sign_ed25519_sk_to_seed(seed.data(), data()) == -1)
|
||||
return false;
|
||||
return crypto_sign_seed_keypair(data() + 32, data(), seed.data()) != -1;
|
||||
return crypto_scalarmult_ed25519_base(data() + 32, data()) != -1;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -62,7 +62,10 @@ namespace llarp
|
|||
crypto_sign_ed25519_sk_to_curve25519(enckey.data(), signkey.data());
|
||||
pub.Update(seckey_topublic(signkey));
|
||||
crypto->pqe_keygen(pq);
|
||||
crypto->derive_subkey_secret(derivedSignKey, signkey, 1);
|
||||
if(not crypto->derive_subkey_secret(derivedSignKey, signkey, 1))
|
||||
{
|
||||
LogError("failed to generate derived key");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -176,7 +179,7 @@ namespace llarp
|
|||
buf.cur = buf.base;
|
||||
const SharedSecret k(i.A.Addr());
|
||||
CryptoManager::instance()->xchacha20(buf, k, encrypted.nounce);
|
||||
encrypted.introsetPayload.reserve(buf.sz);
|
||||
encrypted.introsetPayload.resize(buf.sz);
|
||||
std::copy_n(buf.base, buf.sz, encrypted.introsetPayload.data());
|
||||
if(not encrypted.Sign(derivedSignKey))
|
||||
return {};
|
||||
|
|
|
@ -78,7 +78,8 @@ namespace llarp
|
|||
printer.printAttribute("d", derivedSigningKey);
|
||||
printer.printAttribute("n", nounce);
|
||||
printer.printAttribute("s", signedAt);
|
||||
printer.printAttribute("x", introsetPayload);
|
||||
printer.printAttribute(
|
||||
"x", "[" + std::to_string(introsetPayload.size()) + " bytes]");
|
||||
printer.printAttribute("z", sig);
|
||||
return out;
|
||||
}
|
||||
|
@ -114,14 +115,15 @@ namespace llarp
|
|||
return false;
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
return CryptoManager::instance()->sign(sig, k, buf);
|
||||
if(not CryptoManager::instance()->sign(sig, k, buf))
|
||||
return false;
|
||||
LogInfo("signed encrypted introset: ", *this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EncryptedIntroSet::Verify(llarp_time_t now) const
|
||||
{
|
||||
if(signedAt > now)
|
||||
return false;
|
||||
if(IsExpired(now))
|
||||
return false;
|
||||
std::array< byte_t, MAX_INTROSET_SIZE + 128 > tmp;
|
||||
|
@ -130,6 +132,7 @@ namespace llarp
|
|||
copy.sig.Zero();
|
||||
if(not copy.BEncode(&buf))
|
||||
return false;
|
||||
LogInfo("verify encrypted introset: ", copy, " sig = ", sig);
|
||||
buf.sz = buf.cur - buf.base;
|
||||
buf.cur = buf.base;
|
||||
return CryptoManager::instance()->verify(derivedSigningKey, buf, sig);
|
||||
|
|
|
@ -39,6 +39,7 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
|
|||
|
||||
EXPECT_CALL(m_crypto, sign(I.Z, _, _)).WillOnce(Return(true));
|
||||
EXPECT_CALL(m_crypto, verify(_, _, I.Z)).WillOnce(Return(true));
|
||||
EXPECT_CALL(m_crypto, xchacha20(_, _, _)).WillOnce(Return(true));
|
||||
const auto maybe = ident.EncryptAndSignIntroSet(I, now);
|
||||
ASSERT_TRUE(maybe.has_value());
|
||||
ASSERT_TRUE(maybe->Verify(now));
|
||||
|
@ -75,6 +76,9 @@ TEST_F(ServiceIdentityTest, EnsureKeys)
|
|||
|
||||
const SecretKey k;
|
||||
|
||||
EXPECT_CALL(m_crypto, derive_subkey_secret(_, _, _))
|
||||
.WillRepeatedly(Return(true));
|
||||
|
||||
EXPECT_CALL(m_crypto, identity_keygen(_))
|
||||
.WillOnce(WithArg< 0 >(FillArg< SecretKey >(0x02)));
|
||||
|
||||
|
@ -121,3 +125,61 @@ TEST_F(ServiceIdentityTest, EnsureKeysBrokenFile)
|
|||
service::Identity identity;
|
||||
ASSERT_FALSE(identity.EnsureKeys(p.string(), false));
|
||||
}
|
||||
|
||||
struct RealCryptographyTest : public ::testing::Test
|
||||
{
|
||||
std::unique_ptr< CryptoManager > _manager;
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
_manager = std::make_unique< CryptoManager >(new sodium::CryptoLibSodium());
|
||||
}
|
||||
|
||||
void
|
||||
TearDown()
|
||||
{
|
||||
_manager.reset();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(RealCryptographyTest, TestGenerateDeriveKey)
|
||||
{
|
||||
SecretKey root_key;
|
||||
SecretKey sub_key;
|
||||
PubKey sub_pubkey;
|
||||
auto crypto = CryptoManager::instance();
|
||||
crypto->identity_keygen(root_key);
|
||||
ASSERT_TRUE(crypto->derive_subkey_secret(sub_key, root_key, 1));
|
||||
ASSERT_TRUE(crypto->derive_subkey(sub_pubkey, root_key.toPublic(), 1));
|
||||
ASSERT_EQ(sub_key.toPublic(), sub_pubkey);
|
||||
}
|
||||
|
||||
TEST_F(RealCryptographyTest, TestEncryptAndSignIntroSet)
|
||||
{
|
||||
service::Identity ident;
|
||||
ident.RegenerateKeys();
|
||||
service::Address addr;
|
||||
ASSERT_TRUE(ident.pub.CalculateAddress(addr.as_array()));
|
||||
service::IntroSet I;
|
||||
auto now = time_now_ms();
|
||||
I.T = now;
|
||||
while(I.I.size() < 10)
|
||||
{
|
||||
service::Introduction intro;
|
||||
intro.expiresAt = now + (path::default_lifetime / 2);
|
||||
intro.router.Randomize();
|
||||
intro.pathID.Randomize();
|
||||
I.I.emplace_back(std::move(intro));
|
||||
}
|
||||
|
||||
const auto maybe = ident.EncryptAndSignIntroSet(I, now);
|
||||
ASSERT_TRUE(maybe.has_value());
|
||||
llarp::LogInfo("introset=", maybe.value());
|
||||
ASSERT_TRUE(maybe->Verify(now));
|
||||
PubKey blind_key;
|
||||
const PubKey root_key(addr.as_array());
|
||||
auto crypto = CryptoManager::instance();
|
||||
ASSERT_TRUE(crypto->derive_subkey(blind_key, root_key, 1));
|
||||
ASSERT_EQ(blind_key, root_key);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue