Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yf/crypto algo alignment #2794

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2c4b621
Decoupling crypto digest to choose crypto algos
Apr 1, 2022
9926bb8
Digest generation using OpenSSL library (SHA2_256 & SHA3_256 algos).
Apr 12, 2022
e946d07
Commit contains changes:-
Apr 12, 2022
4123058
Review comments addressed.
Apr 13, 2022
2fffff3
UT cases added for Crypto++ and OpenSSL libraries SHA hashing.
Apr 13, 2022
a0cf796
Digest generation using OpenSSL library (SHA2_256 & SHA3_256 algos).
Apr 12, 2022
b5fb31d
Commit contains changes:-
Apr 12, 2022
6654f72
Review comments addressed.
Apr 13, 2022
0fd7cea
Add log messages to apollo
WildFireFlum May 24, 2022
e10fec2
Add initial eddsa multisig signer implementation
WildFireFlum May 24, 2022
cb202e5
Make Apollo's BFTConfig support more valid configurations
WildFireFlum May 24, 2022
657affd
Add EdDSA logger and thread local sequences to log messages
WildFireFlum May 25, 2022
1e9d11d
Update license preface of newly added files
WildFireFlum May 25, 2022
365917f
Make relic linkage configurable
WildFireFlum May 30, 2022
48c87d6
Implement generic threshsign benchmark
WildFireFlum Jun 8, 2022
905f8a3
Make IThresholdFactory interface return smart pointer
WildFireFlum Jun 12, 2022
d0d3ffd
Prepare code for integration with new signer/verifier interface
WildFireFlum Jun 13, 2022
90a7143
Add eddsa key validation
WildFireFlum Jun 14, 2022
25a6bad
Pass clang-tidy
WildFireFlum Jun 15, 2022
61b621a
Implement eddsa multisig share verification, extract a constant in Ap…
WildFireFlum Jun 22, 2022
7087e0b
Fixed compilation issue.
Jul 5, 2022
354b861
Vmwathena compilation fixed.
Jul 5, 2022
2f50a11
Rename eddsa header
WildFireFlum Jul 26, 2022
cf57ce0
Add interface files
WildFireFlum Jul 26, 2022
0dbecbe
Add main components
WildFireFlum Jul 26, 2022
a1af918
Add tests
WildFireFlum Jul 26, 2022
998d975
Add msgs
WildFireFlum Jul 26, 2022
47731f3
Add threshsign
WildFireFlum Jul 26, 2022
928e875
Add compilation
WildFireFlum Jul 26, 2022
594e531
This commit contains:-
Jul 27, 2022
548bc4c
Review comments addressed.
Aug 4, 2022
3dd7560
Tidy-check compilation issue resolved.
Aug 11, 2022
f73a522
Review comments addressed - 2.
Aug 22, 2022
e7e5bfa
Compilation error fixed.
Aug 25, 2022
6381c01
Merge pull request #13 from pkthapa/compilation-issue-after-final-merge
pkthapa Aug 25, 2022
86f1f0d
Introduced variable to choose signing algo in apollo tests.
Aug 29, 2022
d58a4f1
Merge pull request #14 from pkthapa/review-comments
WildFireFlum Sep 5, 2022
bbbbbb8
Removed SHA3_256 digest algorithm as per spec review meeting comment..
Sep 5, 2022
c7ce105
Merge pull request #15 from pkthapa/spec-review-comments
pkthapa Sep 5, 2022
85ce0a7
Prepare code for integration with new signer/verifier interface
WildFireFlum Jun 13, 2022
fecf5af
Pass clang-tidy
WildFireFlum Jun 15, 2022
04a4614
Add algorithm metadata to chain upon initial main key exchange
WildFireFlum Jul 20, 2022
4a8e54e
Move crypto.hpp to util/crypto.hpp
WildFireFlum Sep 6, 2022
7623ec6
Move digest utils
WildFireFlum Sep 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .clang-tidy-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@

# Ignore all protobuf/gRPC generated source files
*.pb.cc
# ignore test as it tests moved obkects
*lru_cache_test.cpp
# ignore test as it tests moved objects
*lru_cache_test.cpp
*BenchmarkThreshsign.cpp
3 changes: 2 additions & 1 deletion .github/workflows/asan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ jobs:
run: |
script -q -e -c "make pull"
sudo df -h
script -q -e -c "CONCORD_BFT_CMAKE_OMIT_TEST_OUTPUT=TRUE CONCORD_BFT_CMAKE_KEEP_APOLLO_LOGS=FALSE CONCORD_BFT_CMAKE_ASAN=TRUE CONCORD_BFT_CMAKE_USE_FAKE_CLOCK_IN_TIME_SERVICE=TRUE make build" \
script -q -e -c "CONCORD_BFT_CMAKE_OMIT_TEST_OUTPUT=TRUE CONCORD_BFT_CMAKE_KEEP_APOLLO_LOGS=FALSE CONCORD_BFT_CMAKE_ASAN=TRUE CONCORD_BFT_CMAKE_USE_FAKE_CLOCK_IN_TIME_SERVICE=TRUE \
make build" \
&& script -q -e -c "make test"
- name: Check if ASAN passed
if: always()
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/codecoverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ jobs:
script -q -e -c "make pull"
sudo df -h
script -q -e -c "CONCORD_BFT_CONTAINER_CC=clang CONCORD_BFT_CONTAINER_CXX=clang++ \
CONCORD_BFT_CMAKE_CODECOVERAGE=TRUE CONCORD_BFT_CMAKE_TRANSPORT=UDP make build" && script -q -e -c "make test"
CONCORD_BFT_CMAKE_CODECOVERAGE=TRUE CONCORD_BFT_CMAKE_TRANSPORT=UDP \
make build" && script -q -e -c "make test"
continue-on-error: true

- name: Generate code coverage report for apollo tests
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tsan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ jobs:
run: |
script -q -e -c "make pull"
sudo df -h
script -q -e -c "CONCORD_BFT_CMAKE_OMIT_TEST_OUTPUT=TRUE CONCORD_BFT_CMAKE_KEEP_APOLLO_LOGS=FALSE CONCORD_BFT_CMAKE_TSAN=TRUE CONCORD_BFT_CMAKE_USE_FAKE_CLOCK_IN_TIME_SERVICE=TRUE make build" \
script -q -e -c "CONCORD_BFT_CMAKE_OMIT_TEST_OUTPUT=TRUE CONCORD_BFT_CMAKE_KEEP_APOLLO_LOGS=FALSE CONCORD_BFT_CMAKE_TSAN=TRUE CONCORD_BFT_CMAKE_USE_FAKE_CLOCK_IN_TIME_SERVICE=TRUE \
make build" \
&& script -q -e -c "make test"
- name: Check if TSAN passed
if: always()
Expand Down
13 changes: 10 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Enable debug or release builds" FORCE)
endif()

if (NOT DEFINED USE_LOG4CPP)
option(USE_LOG4CPP "Enable LOG4CPP" ON)
if(NOT DEFINED USE_LOG4CPP)
option(USE_LOG4CPP "Enable LOG4CPP" ON)
endif()

option(USE_RELIC "Enable usage of Relic library for BLS threshold signature generation/verification" OFF)
option(RUN_APOLLO_TESTS "Enable Apollo tests run" ON)
option(KEEP_APOLLO_LOGS "Retains logs from replicas in separate folder for each test in build/tests/apollo/logs" ON)
option(TXN_SIGNING_ENABLED "Enable External concord client transcattion signing" ON)
Expand All @@ -43,11 +44,17 @@ option(USE_JSON "Enable use of JSON library" ON)
option(USE_HTTPLIB "Enable use of httplib" ON)
option(USE_GRPC "Enable GRPC and Protobuf" ON)
option(USE_OPENSSL "Enable use of OpenSSL" ON)
option(USE_EDDSA_OPENSSL "Enable use of EdDSA's OpenSSL implementation for signature generation and verification" ON)
option(BUILD_THIRDPARTY "Wheter to build third party librarie or use preinstalled ones" OFF)
option(CODECOVERAGE "Enable Code Coverage Metrics in Clang" OFF)
option(ENABLE_RESTART_RECOVERY_TESTS "Enable tests for restart recovery" OFF)

if(USE_OPENSSL AND NOT BUILD_THIRDPARTY)
if(NOT (USE_EDDSA_OPENSSL OR USE_RELIC))
message(FATAL_ERROR "At least one threshold/multisig implementation needs to be chosen, "
"Define at least one of the following cmake options: [USE_EDDSA_OPENSSL, USE_RELIC]")
endif()

if((USE_OPENSSL OR USE_EDDSA_OPENSSL) AND NOT BUILD_THIRDPARTY)
set(OPENSSL_ROOT_DIR /usr/local/ssl) # not to confuse with system ssl libs
endif()

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CONCORD_BFT_DOCKER_REPO?=concordbft/
CONCORD_BFT_DOCKER_IMAGE?=concord-bft
CONCORD_BFT_DOCKER_IMAGE_VERSION?=0.44
CONCORD_BFT_DOCKER_IMAGE_VERSION?=0.45
CONCORD_BFT_DOCKER_CONTAINER?=concord-bft

CONCORD_BFT_DOCKERFILE?=Dockerfile
Expand Down
9 changes: 3 additions & 6 deletions bftengine/include/bcstatetransfer/SimpleBCStateTransfer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
#include "bftengine/IStateTransfer.hpp"
#include "Metrics.hpp"
#include "kvstream.h"
#include "Digest.hpp"

using concord::util::digest::Digest;
using concord::util::digest::BlockDigest;
#include "crypto/digest.hpp"

namespace concord {
namespace storage {
Expand All @@ -48,7 +45,7 @@ namespace bcst {
// blocks.
// Blocks are numbered. The first block should be block number 1.

// represnts a digest
// represents a digest
#pragma pack(push, 1)
struct StateTransferDigest {
char content[DIGEST_SIZE];
Expand All @@ -61,7 +58,7 @@ void computeBlockDigest(const uint64_t blockId,
const uint32_t blockSize,
StateTransferDigest *outDigest);

BlockDigest computeBlockDigest(const uint64_t blockId, const char *block, const uint32_t blockSize);
concord::crypto::BlockDigest computeBlockDigest(const uint64_t blockId, const char *block, const uint32_t blockSize);

// This interface should be implemented by the application/storage layer.
// It is used by the state transfer module.
Expand Down
23 changes: 21 additions & 2 deletions bftengine/include/bftengine/CryptoManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "ReplicaConfig.hpp"
#include "IKeyExchanger.hpp"
#include "Logger.hpp"
#include "crypto/crypto.hpp"

namespace bftEngine {
typedef std::int64_t SeqNum; // TODO [TK] redefinition
Expand Down Expand Up @@ -51,11 +52,29 @@ class CryptoManager : public IKeyExchanger, public IMultiSigKeyGenerator {
std::shared_ptr<IThresholdVerifier> thresholdVerifierForOptimisticCommit(const SeqNum sn) const {
return get(sn)->thresholdVerifierForOptimisticCommit_;
}

std::unique_ptr<Cryptosystem>& getLatestCryptoSystem() const { return cryptoSystems_.rbegin()->second->cryptosys_; }

/**
* @return An algorithm identifier for the latest threshold signature scheme
*/
concord::crypto::SignatureAlgorithm getLatestSignatureAlgorithm() const {
const std::unordered_map<std::string, concord::crypto::SignatureAlgorithm> typeToAlgorithm{
{MULTISIG_BLS_SCHEME, concord::crypto::SignatureAlgorithm::BLS},
{THRESHOLD_BLS_SCHEME, concord::crypto::SignatureAlgorithm::BLS},
{MULTISIG_EDDSA_SCHEME, concord::crypto::SignatureAlgorithm::EdDSA},
};
auto currentType = getLatestCryptoSystem()->getType();
return typeToAlgorithm.at(currentType);
}

// IMultiSigKeyGenerator methods
std::pair<std::string, std::string> generateMultisigKeyPair() override {
std::tuple<std::string, std::string, concord::crypto::SignatureAlgorithm> generateMultisigKeyPair() override {
LOG_INFO(logger(), "Generating new multisig key pair");
return cryptoSystems_.rbegin()->second->cryptosys_->generateNewKeyPair();
auto [priv, pub] = getLatestCryptoSystem()->generateNewKeyPair();
return {priv, pub, getLatestSignatureAlgorithm()};
}

// IKeyExchanger methods
// onPrivateKeyExchange and onPublicKeyExchange callbacks for a given checkpoint may be called in a different order.
// Therefore the first called will create a CryptoSys
Expand Down
7 changes: 4 additions & 3 deletions bftengine/include/bftengine/IKeyExchanger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
// file.

#pragma once
#include "crypto_utils.hpp"
#include <string>
#include <cstdint>
#include <tuple>
#include "crypto/crypto.hpp"

// Interface for objects that need to be notified on key rotation
class IKeyExchanger {
Expand All @@ -25,11 +26,11 @@ class IKeyExchanger {
class IMultiSigKeyGenerator {
public:
virtual ~IMultiSigKeyGenerator() {}
virtual std::pair<std::string, std::string> generateMultisigKeyPair() = 0;
virtual std::tuple<std::string, std::string, concord::crypto::SignatureAlgorithm> generateMultisigKeyPair() = 0;
};

class IClientPublicKeyStore {
public:
virtual ~IClientPublicKeyStore() = default;
virtual void setClientPublicKey(uint16_t clientId, const std::string& key, concord::util::crypto::KeyFormat) = 0;
virtual void setClientPublicKey(uint16_t clientId, const std::string& key, concord::crypto::KeyFormat) = 0;
};
15 changes: 10 additions & 5 deletions bftengine/include/bftengine/KeyExchangeManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
#include "Metrics.hpp"
#include "secrets_manager_impl.h"
#include "SysConsts.hpp"
#include "crypto_utils.hpp"
#include "crypto/crypto.hpp"
#include <future>

namespace bftEngine::impl {

class IInternalBFTClient;
Expand All @@ -30,7 +31,7 @@ class KeyExchangeManager {
public:
void exchangeTlsKeys(const SeqNum& bft_sn);
// Generates and publish key to consensus
void sendKeyExchange(const SeqNum&);
void generateConsensusKeyAndSendInternalClientMsg(const SeqNum& sn);
// Send the current main public key of the replica to consensus
void sendMainPublicKey();
// Generates and publish the first replica's key,
Expand All @@ -48,7 +49,7 @@ class KeyExchangeManager {
uint32_t liveClusterSize = ReplicaConfig::instance().waitForFullCommOnStartup ? clusterSize_ : quorumSize_;
bool exchange_self_keys = publicKeys_.keyExists(ReplicaConfig::instance().replicaId);
return ReplicaConfig::instance().getkeyExchangeOnStart()
? (publicKeys_.numOfExchangedReplicas() >= liveClusterSize - 1) && exchange_self_keys
? (publicKeys_.numOfExchangedReplicas() + 1 >= liveClusterSize) && exchange_self_keys
: true;
}
const std::string kInitialKeyExchangeCid = "KEY-EXCHANGE-";
Expand All @@ -64,10 +65,10 @@ class KeyExchangeManager {
void sendInitialClientsKeys(const std::string&);
void onPublishClientsKeys(const std::string& keys, std::optional<std::string> bootstrap_keys);
// called on a new client key
void onClientPublicKeyExchange(const std::string& key, concord::util::crypto::KeyFormat, NodeIdType clientId);
void onClientPublicKeyExchange(const std::string& key, concord::crypto::KeyFormat, NodeIdType clientId);
// called when client keys are loaded
void loadClientPublicKey(const std::string& key,
concord::util::crypto::KeyFormat,
concord::crypto::KeyFormat,
NodeIdType clientId,
bool saveToReservedPages);
///////// end - Clients public keys interface///////////////
Expand All @@ -92,11 +93,15 @@ class KeyExchangeManager {
std::string cid;
// seqnum of key exchange request
SeqNum sn;
// Key algorithm
concord::crypto::SignatureAlgorithm algorithm;

void clear() {
priv.clear();
pub.clear();
cid.clear();
sn = 0;
algorithm = concord::crypto::SignatureAlgorithm::Uninitialized;
}
} generated;
// seqnum -> private key
Expand Down
8 changes: 6 additions & 2 deletions bftengine/include/bftengine/KeyExchangeMsg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ struct KeyExchangeMsg : public concord::serialize::SerializableFactory<KeyExchan
uint16_t repID;
uint64_t generated_sn;
uint64_t epoch;
uint16_t algorithm;

std::string toString() const {
std::stringstream ss;
ss << "pubkey [" << pubkey << "] replica id [" << repID << "] generate sequence number [" << generated_sn
<< "] epoch [" << epoch << "]";
<< "] epoch [" << epoch << "]"
<< " algorithm [" << algorithm << "]";
return ss.str();
}
static KeyExchangeMsg deserializeMsg(const char* serializedMsg, const int& size) {
Expand All @@ -38,19 +40,21 @@ struct KeyExchangeMsg : public concord::serialize::SerializableFactory<KeyExchan
}

protected:
const std::string getVersion() const override { return "1"; }
const std::string getVersion() const override { return "2"; }
void serializeDataMembers(std::ostream& outStream) const override {
serialize(outStream, op);
serialize(outStream, pubkey);
serialize(outStream, repID);
serialize(outStream, generated_sn);
serialize(outStream, epoch);
serialize(outStream, algorithm);
}
void deserializeDataMembers(std::istream& inStream) override {
deserialize(inStream, op);
deserialize(inStream, pubkey);
deserialize(inStream, repID);
deserialize(inStream, generated_sn);
deserialize(inStream, epoch);
deserialize(inStream, algorithm);
}
};
25 changes: 22 additions & 3 deletions bftengine/include/bftengine/ReplicaConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
#include <chrono>
#include "string.hpp"
#include "kvstream.h"

#include "Serializable.h"
#include "crypto/factory.hpp"

namespace bftEngine {

Expand Down Expand Up @@ -281,6 +280,16 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
"the concord-ctl script");
CONFIG_PARAM(kvBlockchainVersion, std::uint32_t, 1u, "Default version of KV blockchain for this replica");

CONFIG_PARAM(replicaMsgSigningAlgo,
concord::crypto::SIGN_VERIFY_ALGO,
concord::crypto::SIGN_VERIFY_ALGO::EDDSA,
"A flag to specify the replica message signing algorithm. It is defaulted to use EDDSA algo.");

CONFIG_PARAM(operatorMsgSigningAlgo,
concord::crypto::SIGN_VERIFY_ALGO,
concord::crypto::SIGN_VERIFY_ALGO::EDDSA,
"A flag to specify the operator message signing algorithm. It is defaulted to use EDDSA algo.");

// Parameter to enable/disable waiting for transaction data to be persisted.
// Not predefined configuration parameters
// Example of usage:
Expand Down Expand Up @@ -406,6 +415,8 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
serialize(outStream, diagnosticsServerPort);
serialize(outStream, useUnifiedCertificates);
serialize(outStream, kvBlockchainVersion);
serialize(outStream, operatorMsgSigningAlgo);
serialize(outStream, replicaMsgSigningAlgo);
}
void deserializeDataMembers(std::istream& inStream) {
deserialize(inStream, isReadOnly);
Expand Down Expand Up @@ -506,6 +517,8 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
deserialize(inStream, diagnosticsServerPort);
deserialize(inStream, useUnifiedCertificates);
deserialize(inStream, kvBlockchainVersion);
deserialize(inStream, operatorMsgSigningAlgo);
deserialize(inStream, replicaMsgSigningAlgo);
}

private:
Expand Down Expand Up @@ -591,6 +604,10 @@ inline std::ostream& operator<<(std::ostream& os, const ReplicaConfig& rc) {
rc.adaptivePruningIntervalPeriod,
rc.dbSnapshotIntervalSeconds.count());
os << ",";
const auto replicaMsgSignAlgo =
(concord::crypto::SIGN_VERIFY_ALGO::RSA == rc.replicaMsgSigningAlgo) ? "rsa" : "eddsa";
const auto operatorMsgSignAlgo =
(concord::crypto::SIGN_VERIFY_ALGO::ECDSA == rc.operatorMsgSigningAlgo) ? "ecdsa" : "eddsa";
os << KVLOG(rc.dbCheckpointMonitorIntervalSeconds.count(),
rc.dbCheckpointDiskSpaceThreshold,
rc.enableMultiplexChannel,
Expand All @@ -599,7 +616,9 @@ inline std::ostream& operator<<(std::ostream& os, const ReplicaConfig& rc) {
rc.enablePreProcessorMemoryPool,
rc.diagnosticsServerPort,
rc.useUnifiedCertificates,
rc.kvBlockchainVersion);
rc.kvBlockchainVersion,
replicaMsgSignAlgo,
operatorMsgSignAlgo);
os << ", ";
for (auto& [param, value] : rc.config_params_) os << param << ": " << value << "\n";
return os;
Expand Down
12 changes: 5 additions & 7 deletions bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,13 @@ class Communication : public ICommunication {
uint16_t repId_;
};

class InternalSigner : public concord::util::crypto::ISigner {
class InternalSigner : public concord::crypto::ISigner {
public:
std::string sign(const std::string& data) override {
std::string out;
out.resize(bftEngine::impl::SigManager::instance()->getMySigLength());
bftEngine::impl::SigManager::instance()->sign(data.data(), data.size(), out.data(), signatureLength());
return out;
size_t signBuffer(const concord::Byte* dataIn, size_t dataLen, concord::Byte* sigOutBuffer) override {
return bftEngine::impl::SigManager::instance()->sign(dataIn, dataLen, sigOutBuffer);
}
uint32_t signatureLength() const override { return bftEngine::impl::SigManager::instance()->getMySigLength(); }

size_t signatureLength() const override { return bftEngine::impl::SigManager::instance()->getMySigLength(); }
std::string getPrivKey() const override { return ""; }
};

Expand Down
Loading