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_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libdash_util_a_SOURCES = \
|
||||
crypto/bls_ies.cpp \
|
||||
crypto/bls_ies.h \
|
||||
support/lockedpool.cpp \
|
||||
chainparamsbase.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