Add simple helpers/wrappers for BLS+AES based integrated encryption schemes (IES)

This commit is contained in:
Alexander Block 2018-05-24 11:29:48 +02:00
parent 9ccf6f584d
commit aa3b0aa8a4
3 changed files with 302 additions and 0 deletions

View File

@ -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
View 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
View 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