Add simple helpers/wrappers for BLS+AES based integrated encryption schemes (IES)
This commit is contained in:
parent
9ccf6f584d
commit
aa3b0aa8a4
@ -422,6 +422,8 @@ libdash_common_a_SOURCES = \
|
|||||||
libdash_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
libdash_util_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||||
libdash_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
libdash_util_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
libdash_util_a_SOURCES = \
|
libdash_util_a_SOURCES = \
|
||||||
|
crypto/bls_ies.cpp \
|
||||||
|
crypto/bls_ies.h \
|
||||||
support/lockedpool.cpp \
|
support/lockedpool.cpp \
|
||||||
chainparamsbase.cpp \
|
chainparamsbase.cpp \
|
||||||
clientversion.cpp \
|
clientversion.cpp \
|
||||||
|
136
src/crypto/bls_ies.cpp
Normal file
136
src/crypto/bls_ies.cpp
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Copyright (c) 2018 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "bls_ies.h"
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
#include "random.h"
|
||||||
|
#include "streams.h"
|
||||||
|
|
||||||
|
#include "aes.h"
|
||||||
|
|
||||||
|
template <typename Out>
|
||||||
|
static bool EncryptBlob(const void* in, size_t inSize, Out& out, const void* symKey, const void* iv)
|
||||||
|
{
|
||||||
|
out.resize(inSize);
|
||||||
|
|
||||||
|
AES256CBCEncrypt enc((const unsigned char*)symKey, (const unsigned char*)iv, false);
|
||||||
|
int w = enc.Encrypt((const unsigned char*)in, (int)inSize, (unsigned char*)out.data());
|
||||||
|
return w == (int)inSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Out>
|
||||||
|
static bool DecryptBlob(const void* in, size_t inSize, Out& out, const void* symKey, const void* iv)
|
||||||
|
{
|
||||||
|
out.resize(inSize);
|
||||||
|
|
||||||
|
AES256CBCDecrypt enc((const unsigned char*)symKey, (const unsigned char*)iv, false);
|
||||||
|
int w = enc.Decrypt((const unsigned char*)in, (int)inSize, (unsigned char*)out.data());
|
||||||
|
return w == (int)inSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBLSIESEncryptedBlob::Encrypt(const CBLSPublicKey& peerPubKey, const void* plainTextData, size_t dataSize)
|
||||||
|
{
|
||||||
|
CBLSSecretKey ephemeralSecretKey;
|
||||||
|
ephemeralSecretKey.MakeNewKey();
|
||||||
|
ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
|
||||||
|
GetStrongRandBytes(iv, sizeof(iv));
|
||||||
|
|
||||||
|
CBLSPublicKey pk;
|
||||||
|
if (!pk.DHKeyExchange(ephemeralSecretKey, peerPubKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> symKey;
|
||||||
|
pk.GetBuf(symKey);
|
||||||
|
symKey.resize(32);
|
||||||
|
|
||||||
|
return EncryptBlob(plainTextData, dataSize, data, symKey.data(), iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBLSIESEncryptedBlob::Decrypt(const CBLSSecretKey& secretKey, CDataStream& decryptedDataRet) const
|
||||||
|
{
|
||||||
|
CBLSPublicKey pk;
|
||||||
|
if (!pk.DHKeyExchange(secretKey, ephemeralPubKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> symKey;
|
||||||
|
pk.GetBuf(symKey);
|
||||||
|
symKey.resize(32);
|
||||||
|
|
||||||
|
return DecryptBlob(data.data(), data.size(), decryptedDataRet, symKey.data(), iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CBLSIESMultiRecipientBlobs::Encrypt(const std::vector<CBLSPublicKey>& recipients, const BlobVector& _blobs)
|
||||||
|
{
|
||||||
|
if (recipients.size() != _blobs.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitEncrypt(_blobs.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < _blobs.size(); i++) {
|
||||||
|
if (!Encrypt(i, recipients[i], _blobs[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBLSIESMultiRecipientBlobs::InitEncrypt(size_t count)
|
||||||
|
{
|
||||||
|
ephemeralSecretKey.MakeNewKey();
|
||||||
|
ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
|
||||||
|
GetStrongRandBytes(ivSeed.begin(), ivSeed.size());
|
||||||
|
|
||||||
|
uint256 iv = ivSeed;
|
||||||
|
ivVector.resize(count);
|
||||||
|
blobs.resize(count);
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
ivVector[i] = iv;
|
||||||
|
iv = ::SerializeHash(iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBLSIESMultiRecipientBlobs::Encrypt(size_t idx, const CBLSPublicKey& recipient, const Blob& blob)
|
||||||
|
{
|
||||||
|
assert(idx < blobs.size());
|
||||||
|
|
||||||
|
CBLSPublicKey pk;
|
||||||
|
if (!pk.DHKeyExchange(ephemeralSecretKey, recipient)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> symKey;
|
||||||
|
pk.GetBuf(symKey);
|
||||||
|
symKey.resize(32);
|
||||||
|
|
||||||
|
return EncryptBlob(blob.data(), blob.size(), blobs[idx], symKey.data(), ivVector[idx].begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBLSIESMultiRecipientBlobs::Decrypt(size_t idx, const CBLSSecretKey& sk, Blob& blobRet) const
|
||||||
|
{
|
||||||
|
if (idx >= blobs.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBLSPublicKey pk;
|
||||||
|
if (!pk.DHKeyExchange(sk, ephemeralPubKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> symKey;
|
||||||
|
pk.GetBuf(symKey);
|
||||||
|
symKey.resize(32);
|
||||||
|
|
||||||
|
uint256 iv = ivSeed;
|
||||||
|
for (size_t i = 0; i < idx; i++) {
|
||||||
|
iv = ::SerializeHash(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin());
|
||||||
|
}
|
164
src/crypto/bls_ies.h
Normal file
164
src/crypto/bls_ies.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
// Copyright (c) 2018 The Dash Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef DASH_CRYPTO_BLS_IES_H
|
||||||
|
#define DASH_CRYPTO_BLS_IES_H
|
||||||
|
|
||||||
|
#include "bls.h"
|
||||||
|
#include "streams.h"
|
||||||
|
|
||||||
|
class CBLSIESEncryptedBlob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CBLSPublicKey ephemeralPubKey;
|
||||||
|
unsigned char iv[16];
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
|
||||||
|
bool valid{false};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADD_SERIALIZE_METHODS
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
if (!ser_action.ForRead()) {
|
||||||
|
assert(valid);
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
READWRITE(ephemeralPubKey);
|
||||||
|
READWRITE(FLATDATA(iv));
|
||||||
|
READWRITE(data);
|
||||||
|
if (ser_action.ForRead()) {
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool Encrypt(const CBLSPublicKey& peerPubKey, const void* data, size_t dataSize);
|
||||||
|
bool Decrypt(const CBLSSecretKey& secretKey, CDataStream& decryptedDataRet) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Object>
|
||||||
|
class CBLSIESEncryptedObject : public CBLSIESEncryptedBlob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CBLSIESEncryptedObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Encrypt(const CBLSPublicKey& peerPubKey, const Object& obj, int nVersion)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
CDataStream ds(SER_NETWORK, nVersion);
|
||||||
|
ds << obj;
|
||||||
|
return CBLSIESEncryptedBlob::Encrypt(peerPubKey, ds.data(), ds.size());
|
||||||
|
} catch (std::exception&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decrypt(const CBLSSecretKey& secretKey, Object& objRet, int nVersion) const
|
||||||
|
{
|
||||||
|
CDataStream ds(SER_NETWORK, nVersion);
|
||||||
|
if (!CBLSIESEncryptedBlob::Decrypt(secretKey, ds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ds >> objRet;
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBLSIESMultiRecipientBlobs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<unsigned char> Blob;
|
||||||
|
typedef std::vector<Blob> BlobVector;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CBLSPublicKey ephemeralPubKey;
|
||||||
|
uint256 ivSeed;
|
||||||
|
BlobVector blobs;
|
||||||
|
|
||||||
|
// Used while encrypting. Temporary and only in-memory
|
||||||
|
CBLSSecretKey ephemeralSecretKey;
|
||||||
|
std::vector<uint256> ivVector;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool Encrypt(const std::vector<CBLSPublicKey>& recipients, const BlobVector& _blobs);
|
||||||
|
|
||||||
|
void InitEncrypt(size_t count);
|
||||||
|
bool Encrypt(size_t idx, const CBLSPublicKey& recipient, const Blob& blob);
|
||||||
|
bool Decrypt(size_t idx, const CBLSSecretKey& sk, Blob& blobRet) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ADD_SERIALIZE_METHODS
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||||
|
{
|
||||||
|
READWRITE(ephemeralPubKey);
|
||||||
|
READWRITE(ivSeed);
|
||||||
|
READWRITE(blobs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Object>
|
||||||
|
class CBLSIESMultiRecipientObjects : public CBLSIESMultiRecipientBlobs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<Object> ObjectVector;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool Encrypt(const std::vector<CBLSPublicKey>& recipients, const ObjectVector& _objects, int nVersion)
|
||||||
|
{
|
||||||
|
BlobVector blobs;
|
||||||
|
blobs.resize(_objects.size());
|
||||||
|
|
||||||
|
try {
|
||||||
|
CDataStream ds(SER_NETWORK, nVersion);
|
||||||
|
for (size_t i = 0; i < _objects.size(); i++) {
|
||||||
|
ds.clear();
|
||||||
|
|
||||||
|
ds << _objects[i];
|
||||||
|
blobs[i].assign(ds.begin(), ds.end());
|
||||||
|
}
|
||||||
|
} catch (std::exception&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CBLSIESMultiRecipientBlobs::Encrypt(recipients, blobs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Encrypt(size_t idx, const CBLSPublicKey& recipient, const Object& obj, int nVersion)
|
||||||
|
{
|
||||||
|
CDataStream ds(SER_NETWORK, nVersion);
|
||||||
|
ds << obj;
|
||||||
|
Blob blob(ds.begin(), ds.end());
|
||||||
|
return CBLSIESMultiRecipientBlobs::Encrypt(idx, recipient, blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Decrypt(size_t idx, const CBLSSecretKey& sk, Object& objectRet, int nVersion) const
|
||||||
|
{
|
||||||
|
Blob blob;
|
||||||
|
if (!CBLSIESMultiRecipientBlobs::Decrypt(idx, sk, blob)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
CDataStream ds(blob, SER_NETWORK, nVersion);
|
||||||
|
ds >> objectRet;
|
||||||
|
return true;
|
||||||
|
} catch (std::exception&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DASH_CRYPTO_BLS_IES_H
|
Loading…
Reference in New Issue
Block a user