Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Crypto: implement TweetNaCl via Crypto++, remove SUPERCOP (ref10)
Browse files Browse the repository at this point in the history
Also re-introduces the crypto namespace (lifetime TBD), and implements
SecByteBlock (see monero-project#784).

Resolves monero-project#485. Closes monero-project#345.
anonimal committed Jun 15, 2018

Verified

This commit was signed with the committer’s verified signature. The key has expired.
anonimal 0x914409F1
1 parent 501a4a5 commit 448a9b8
Showing 85 changed files with 226 additions and 5,575 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -53,7 +53,6 @@ option(WITH_OPTIMIZE "Optimization flags" OFF)
option(WITH_PYTHON "Build wrappers which require Boost.Python" OFF)
option(WITH_STATIC "Static build" OFF)
option(WITH_STATIC_DEPS "Static build with static dependencies" OFF)
option(WITH_SUPERCOP "Build Ed25519 using the ref10 implementation from SUPERCOP" ON) # Default ON unless we switch implementations
option(WITH_TESTS "Build unit tests" OFF)
option(WITH_FUZZ_TESTS "Build fuzz tests" OFF)
option(WITH_COTIRE "Enable cotire (compile time reducer) - precompiled header and single compilation unit builds" ${MSVC})
77 changes: 0 additions & 77 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -121,83 +121,6 @@ if(WITH_CRYPTOPP)
${CRYPTOPP_DIR}/crypto_const.h)
endif()

if(WITH_SUPERCOP)
set(EDDSA_DIR "crypto/impl/supercop")
set(EDDSA_SRC
${EDDSA_DIR}/signature.cc
${EDDSA_DIR}/ed25519/fe_0.cc
${EDDSA_DIR}/ed25519/fe_1.cc
${EDDSA_DIR}/ed25519/fe_add.cc
${EDDSA_DIR}/ed25519/fe_cmov.cc
${EDDSA_DIR}/ed25519/fe_copy.cc
${EDDSA_DIR}/ed25519/fe_frombytes.cc
${EDDSA_DIR}/ed25519/fe_invert.cc
${EDDSA_DIR}/ed25519/fe_isnegative.cc
${EDDSA_DIR}/ed25519/fe_isnonzero.cc
${EDDSA_DIR}/ed25519/fe_mul.cc
${EDDSA_DIR}/ed25519/fe_neg.cc
${EDDSA_DIR}/ed25519/fe_pow22523.cc
${EDDSA_DIR}/ed25519/fe_sq.cc
${EDDSA_DIR}/ed25519/fe_sq2.cc
${EDDSA_DIR}/ed25519/fe_sub.cc
${EDDSA_DIR}/ed25519/fe_tobytes.cc
${EDDSA_DIR}/ed25519/ge_add.cc
${EDDSA_DIR}/ed25519/ge_double_scalarmult.cc
${EDDSA_DIR}/ed25519/ge_frombytes.cc
${EDDSA_DIR}/ed25519/ge_madd.cc
${EDDSA_DIR}/ed25519/ge_msub.cc
${EDDSA_DIR}/ed25519/ge_p1p1_to_p2.cc
${EDDSA_DIR}/ed25519/ge_p1p1_to_p3.cc
${EDDSA_DIR}/ed25519/ge_p2_0.cc
${EDDSA_DIR}/ed25519/ge_p2_dbl.cc
${EDDSA_DIR}/ed25519/ge_p3_0.cc
${EDDSA_DIR}/ed25519/ge_p3_dbl.cc
${EDDSA_DIR}/ed25519/ge_p3_to_cached.cc
${EDDSA_DIR}/ed25519/ge_p3_to_p2.cc
${EDDSA_DIR}/ed25519/ge_p3_tobytes.cc
${EDDSA_DIR}/ed25519/ge_precomp_0.cc
${EDDSA_DIR}/ed25519/ge_scalarmult_base.cc
${EDDSA_DIR}/ed25519/ge_sub.cc
${EDDSA_DIR}/ed25519/ge_tobytes.cc
${EDDSA_DIR}/ed25519/keypair.cc
${EDDSA_DIR}/ed25519/open.cc
${EDDSA_DIR}/ed25519/sc_muladd.cc
${EDDSA_DIR}/ed25519/sc_reduce.cc
${EDDSA_DIR}/ed25519/sign.cc
${EDDSA_DIR}/ed25519/verify.cc
${EDDSA_DIR}/ed25519/api.h
${EDDSA_DIR}/ed25519/base.h
${EDDSA_DIR}/ed25519/base2.h
${EDDSA_DIR}/ed25519/crypto_hash_sha512.h
${EDDSA_DIR}/ed25519/crypto_int32.h
${EDDSA_DIR}/ed25519/crypto_int64.h
${EDDSA_DIR}/ed25519/crypto_sign.h
${EDDSA_DIR}/ed25519/crypto_uint32.h
${EDDSA_DIR}/ed25519/crypto_uint64.h
${EDDSA_DIR}/ed25519/crypto_verify_32.h
${EDDSA_DIR}/ed25519/d.h
${EDDSA_DIR}/ed25519/d2.h
${EDDSA_DIR}/ed25519/ed25519_ref10.h
${EDDSA_DIR}/ed25519/fe.h
${EDDSA_DIR}/ed25519/ge.h
${EDDSA_DIR}/ed25519/ge_add.h
${EDDSA_DIR}/ed25519/ge_madd.h
${EDDSA_DIR}/ed25519/ge_msub.h
${EDDSA_DIR}/ed25519/ge_p2_dbl.h
${EDDSA_DIR}/ed25519/ge_sub.h
${EDDSA_DIR}/ed25519/pow22523.h
${EDDSA_DIR}/ed25519/pow225521.h
${EDDSA_DIR}/ed25519/sc.h
${EDDSA_DIR}/ed25519/sqrtm1.h)

# Disable unity build for eddsa files
foreach(eddsa_file IN LISTS EDDSA_SRC)
set_property(SOURCE ${eddsa_file} PROPERTY COTIRE_EXCLUDED TRUE)
endforeach()

target_sources(kovri-core PRIVATE ${EDDSA_SRC})
endif()

# Add definition for our implementation (must be here or in root recipe)
target_link_libraries(kovri-core PRIVATE libminiupnpc-static)

139 changes: 136 additions & 3 deletions src/core/crypto/impl/cryptopp/signature.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** //
* Copyright (c) 2013-2017, The Kovri I2P Router Project //
* Copyright (c) 2013-2018, The Kovri I2P Router Project //
* //
* All rights reserved. //
* //
@@ -36,11 +36,15 @@
#include <cryptopp/dsa.h>
#include <cryptopp/eccrypto.h>
#include <cryptopp/integer.h>
#include <cryptopp/naclite.h>
#include <cryptopp/oids.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/secblock.h>

#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <memory>
@@ -50,11 +54,11 @@

#include "core/crypto/rand.h"

#include "core/util/log.h"

namespace kovri {
namespace core {

// TODO(anonimal): remove pimpl, see #785

/**
*
* DSA
@@ -761,6 +765,7 @@ class RSARawVerifier {
if (buf.size() < Hash::DIGESTSIZE)
return false; // Can't verify digest longer than key
// We assume digest is right aligned, at least for PKCS#1 v1.5 padding
// TODO(anonimal): don't use memcmp
return !std::memcmp(
buf.data() + (buf.size() - Hash::DIGESTSIZE),
digest.data(),
@@ -807,5 +812,133 @@ bool RSASHA5124096RawVerifier::Verify(
return m_RSASHA5124096RawVerifierPimpl->Verify(signature);
}

/**
*
* Ed25519
*
*/

/// @class Ed25519VerifierImpl
/// @brief Implementation class for the EdDSA Ed25519 verifier
class Ed25519Verifier::Ed25519VerifierImpl
{
public:
Ed25519VerifierImpl(const std::uint8_t* pk) : m_Pk(pk, crypto::PkLen::Ed25519)
{
}

bool Verify(
const std::uint8_t* m,
const std::size_t mlen,
const std::uint8_t* sig) const
{
// Combine message with given signature
CryptoPP::SecByteBlock sm(crypto::SigLen::Ed25519 + mlen);
std::copy(sig, sig + crypto::SigLen::Ed25519, sm.begin());
std::copy(m, m + mlen, sm.begin() + crypto::SigLen::Ed25519);

// Verify
CryptoPP::SecByteBlock rm(mlen + crypto::SigLen::Ed25519);
CryptoPP::word64 rmlen;

int const ret(CryptoPP::NaCl::crypto_sign_open(
rm, &rmlen, sm.data(), sm.size(), m_Pk.data()));
assert(rmlen == sm.size());

return !ret;
}

private:
CryptoPP::SecByteBlock m_Pk;
};

Ed25519Verifier::Ed25519Verifier(const std::uint8_t* pk)
: m_Ed25519VerifierPimpl(std::make_unique<Ed25519VerifierImpl>(pk))
{
}

Ed25519Verifier::~Ed25519Verifier() {}

bool Ed25519Verifier::Verify(
const std::uint8_t* m,
const std::size_t mlen,
const std::uint8_t* sig) const
{
return m_Ed25519VerifierPimpl->Verify(m, mlen, sig);
}

/// @class Ed25519SignerImpl
/// @brief Implementation class for the EdDSA Ed25519 signer
class Ed25519Signer::Ed25519SignerImpl
{
public:
Ed25519SignerImpl(const std::uint8_t* sk, const std::uint8_t* pk)
: m_Sk(sk, crypto::SkLen::Ed25519), m_Pk(pk, crypto::PkLen::Ed25519)
{
}

Ed25519SignerImpl(const std::uint8_t* sk)
: m_Sk(sk, crypto::SkLen::Ed25519), m_Pk(crypto::PkLen::Ed25519)
{
// Create keypair
if (CryptoPP::NaCl::crypto_sign_keypair(
m_Pk.data(),
m_Sk.data(),
false /* Don't clobber given private key */))
throw CryptoPP::Exception(
CryptoPP::Exception::OTHER_ERROR, "could not create ed25519 keypair");
}

void Sign(
const std::uint8_t* m,
const std::size_t mlen,
std::uint8_t* signature) const
{
// Signed message length
CryptoPP::word64 smlen;

// Sign message
std::vector<std::uint8_t> sm(crypto::SigLen::Ed25519 + mlen);
if (CryptoPP::NaCl::crypto_sign(sm.data(), &smlen, m, mlen, m_Sk.data()))
throw CryptoPP::Exception(
CryptoPP::Exception::OTHER_ERROR, "could not ed25519 sign message");

// We only want the signature
assert(sm.size() == smlen);
std::copy(sm.begin(), sm.end() - mlen, signature);
}

private:
CryptoPP::SecByteBlock m_Sk; ///< Private key
CryptoPP::SecByteBlock m_Pk; ///< Public key
};

Ed25519Signer::Ed25519Signer(const std::uint8_t* sk)
: m_Ed25519SignerPimpl(std::make_unique<Ed25519SignerImpl>(sk))
{
}

Ed25519Signer::Ed25519Signer(const std::uint8_t* sk, const std::uint8_t* pk)
: m_Ed25519SignerPimpl(std::make_unique<Ed25519SignerImpl>(sk, pk))
{
}

Ed25519Signer::~Ed25519Signer() {}

void Ed25519Signer::Sign(
const std::uint8_t* m,
const std::size_t mlen,
std::uint8_t* sig) const
{
m_Ed25519SignerPimpl->Sign(m, mlen, sig);
}

void CreateEd25519KeyPair(std::uint8_t* sk, std::uint8_t* pk)
{
if (CryptoPP::NaCl::crypto_sign_keypair(pk, sk))
throw CryptoPP::Exception(
CryptoPP::Exception::OTHER_ERROR, "could not create ed25519 keypair");
}

} // namespace core
} // namespace kovri
2 changes: 0 additions & 2 deletions src/core/crypto/impl/supercop/ed25519/CMakeLists.txt

This file was deleted.

4 changes: 0 additions & 4 deletions src/core/crypto/impl/supercop/ed25519/api.h

This file was deleted.

Loading

0 comments on commit 448a9b8

Please sign in to comment.