mirror of https://github.com/oxen-io/lokinet
initial implementation of blinded sign -- not working yet
This commit is contained in:
parent
f7cd10a82e
commit
a487982c49
|
@ -60,6 +60,9 @@ namespace llarp
|
|||
/// ed25519 sign
|
||||
virtual bool
|
||||
sign(Signature &, const SecretKey &, const llarp_buffer_t &) = 0;
|
||||
/// ed25519 sign (custom with derived keys)
|
||||
virtual bool
|
||||
sign(Signature &, const PrivateKey &, const llarp_buffer_t &) = 0;
|
||||
/// ed25519 verify
|
||||
virtual bool
|
||||
verify(const PubKey &, const llarp_buffer_t &, const Signature &) = 0;
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
#include <sodium/crypto_stream_xchacha20.h>
|
||||
#include <sodium/crypto_core_ed25519.h>
|
||||
#include <sodium/crypto_core_ristretto255.h>
|
||||
#include <sodium/randombytes.h>
|
||||
#include <sodium/utils.h>
|
||||
#include <util/mem.hpp>
|
||||
#include <util/endian.hpp>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -175,6 +178,52 @@ namespace llarp
|
|||
!= -1;
|
||||
}
|
||||
|
||||
bool
|
||||
CryptoLibSodium::sign(Signature &sig, const PrivateKey &secret,
|
||||
const llarp_buffer_t &buf)
|
||||
{
|
||||
PubKey pubkey;
|
||||
|
||||
secret.toPublic(pubkey);
|
||||
|
||||
crypto_hash_sha512_state hs;
|
||||
unsigned char nonce[64];
|
||||
unsigned char hram[64];
|
||||
unsigned char mulres[32];
|
||||
unsigned char r_hash_input[32];
|
||||
|
||||
randombytes_buf(r_hash_input, 32);
|
||||
|
||||
// r = H(H(k) || M) where here H(k) is random bytes
|
||||
crypto_hash_sha512_init(&hs);
|
||||
crypto_hash_sha512_update(&hs, r_hash_input, 32);
|
||||
crypto_hash_sha512_update(&hs, buf.base, buf.sz);
|
||||
crypto_hash_sha512_final(&hs, nonce);
|
||||
crypto_core_ed25519_scalar_reduce(nonce, nonce);
|
||||
|
||||
// copy pubkey into sig to make (for now) sig = (R || A)
|
||||
memmove(sig.Lo(), pubkey.data(), 32);
|
||||
|
||||
// R = r * B
|
||||
crypto_scalarmult_ed25519_base(sig.Hi(), nonce);
|
||||
|
||||
// hram = H(R || A || M)
|
||||
crypto_hash_sha512_init(&hs);
|
||||
crypto_hash_sha512_update(&hs, sig.data(), 64);
|
||||
crypto_hash_sha512_update(&hs, buf.base, buf.sz);
|
||||
crypto_hash_sha512_final(&hs, hram);
|
||||
|
||||
// S = r + H(R || A || M) * s, so sig = (R || S)
|
||||
crypto_core_ed25519_scalar_reduce(hram, hram);
|
||||
crypto_core_ed25519_scalar_mul(mulres, hram, secret.data());
|
||||
crypto_core_ed25519_scalar_add(sig.Lo(), mulres, nonce);
|
||||
|
||||
sodium_memzero(r_hash_input, sizeof r_hash_input);
|
||||
sodium_memzero(nonce, sizeof nonce);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CryptoLibSodium::verify(const PubKey &pub, const llarp_buffer_t &buf,
|
||||
const Signature &sig)
|
||||
|
|
|
@ -48,6 +48,9 @@ namespace llarp
|
|||
/// ed25519 sign
|
||||
bool
|
||||
sign(Signature &, const SecretKey &, const llarp_buffer_t &) override;
|
||||
/// ed25519 sign (custom with derived keys)
|
||||
bool
|
||||
sign(Signature &, const PrivateKey &, const llarp_buffer_t &) override;
|
||||
/// ed25519 verify
|
||||
bool
|
||||
verify(const PubKey &, const llarp_buffer_t &,
|
||||
|
@ -92,6 +95,7 @@ namespace llarp
|
|||
|
||||
bool
|
||||
check_identity_privkey(const SecretKey &) override;
|
||||
|
||||
};
|
||||
} // namespace sodium
|
||||
|
||||
|
|
|
@ -113,6 +113,15 @@ namespace llarp
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
sign(Signature &sig, const PrivateKey &key, const llarp_buffer_t &) override
|
||||
{
|
||||
static_assert(Signature::SIZE == PrivateKey::SIZE * 2, "");
|
||||
std::copy(key.begin(), key.end(), sig.begin());
|
||||
std::copy(key.begin(), key.end(), sig.begin() + 32);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
verify(const PubKey &, const llarp_buffer_t &, const Signature &) override
|
||||
{
|
||||
|
|
|
@ -48,9 +48,9 @@ namespace llarp
|
|||
MOCK_METHOD4(derive_subkey_private,
|
||||
bool(PrivateKey &, const SecretKey &, uint64_t, const AlignedBuffer<32> *));
|
||||
|
||||
MOCK_METHOD3(sign,
|
||||
bool(Signature &, const SecretKey &,
|
||||
const llarp_buffer_t &));
|
||||
MOCK_METHOD(bool, sign, (Signature &, const SecretKey &, const llarp_buffer_t &));
|
||||
|
||||
MOCK_METHOD(bool, sign, (Signature &, const PrivateKey &, const llarp_buffer_t &));
|
||||
|
||||
MOCK_METHOD3(verify,
|
||||
bool(const PubKey &, const llarp_buffer_t &,
|
||||
|
|
|
@ -38,7 +38,8 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
|
|||
I.I.emplace_back(std::move(intro));
|
||||
}
|
||||
|
||||
EXPECT_CALL(m_crypto, sign(I.Z, _, _)).WillOnce(Return(true));
|
||||
using ::testing::Matcher;
|
||||
EXPECT_CALL(m_crypto, sign(I.Z, Matcher<const SecretKey &>(_), _)).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);
|
||||
|
@ -222,6 +223,35 @@ TEST_F(RealCryptographyTest, TestGenerateDeriveKey)
|
|||
ASSERT_EQ(Aprime, Aprime_alt);
|
||||
}
|
||||
|
||||
TEST_F(RealCryptographyTest, TestSignUsingDerivedKey)
|
||||
{
|
||||
auto crypto = CryptoManager::instance();
|
||||
SecretKey root_key;
|
||||
crypto->identity_keygen(root_key);
|
||||
|
||||
PrivateKey root_privkey;
|
||||
root_key.toPrivate(root_privkey);
|
||||
|
||||
PrivateKey a;
|
||||
PubKey A;
|
||||
root_key.toPrivate(a);
|
||||
a.toPublic(A);
|
||||
|
||||
PrivateKey aprime; // a'
|
||||
crypto->derive_subkey_private(aprime, root_key, 1);
|
||||
|
||||
PubKey Aprime; // A'
|
||||
crypto->derive_subkey(Aprime, A, 1);
|
||||
|
||||
std::string dummystr = "Jeff loves one-letter variable names.";
|
||||
llarp_buffer_t buf(dummystr.data(), dummystr.size());
|
||||
|
||||
Signature sig;
|
||||
ASSERT_TRUE(crypto->sign(sig, aprime, buf));
|
||||
|
||||
ASSERT_TRUE(crypto->verify(Aprime, buf, sig));
|
||||
}
|
||||
|
||||
TEST_F(RealCryptographyTest, TestEncryptAndSignIntroSet)
|
||||
{
|
||||
service::Identity ident;
|
||||
|
|
Loading…
Reference in New Issue