Line data Source code
1 : // Copyright (c) 2018 The Dash Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include "bls/bls_ies.h"
6 :
7 : #include "crypto/aes.h"
8 : #include "hash.h"
9 : #include "random.h"
10 : #include "streams.h"
11 :
12 : template <typename Out>
13 1806 : static bool EncryptBlob(const void* in, size_t inSize, Out& out, const void* symKey, const void* iv)
14 : {
15 1806 : out.resize(inSize);
16 :
17 1806 : AES256CBCEncrypt enc((const unsigned char*)symKey, (const unsigned char*)iv, false);
18 1806 : int w = enc.Encrypt((const unsigned char*)in, (int)inSize, (unsigned char*)out.data());
19 1806 : return w == (int)inSize;
20 : }
21 :
22 : template <typename Out>
23 1790 : static bool DecryptBlob(const void* in, size_t inSize, Out& out, const void* symKey, const void* iv)
24 : {
25 1790 : out.resize(inSize);
26 :
27 1790 : AES256CBCDecrypt enc((const unsigned char*)symKey, (const unsigned char*)iv, false);
28 1790 : int w = enc.Decrypt((const unsigned char*)in, (int)inSize, (unsigned char*)out.data());
29 1790 : return w == (int)inSize;
30 : }
31 :
32 2 : bool CBLSIESEncryptedBlob::Encrypt(const CBLSPublicKey& peerPubKey, const void* plainTextData, size_t dataSize)
33 : {
34 4 : CBLSSecretKey ephemeralSecretKey;
35 2 : ephemeralSecretKey.MakeNewKey();
36 2 : ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
37 2 : GetStrongRandBytes(iv, sizeof(iv));
38 :
39 2 : CBLSPublicKey pk;
40 2 : if (!pk.DHKeyExchange(ephemeralSecretKey, peerPubKey)) {
41 : return false;
42 : }
43 :
44 4 : std::vector<unsigned char> symKey = pk.ToByteVector();
45 2 : symKey.resize(32);
46 :
47 2 : return EncryptBlob(plainTextData, dataSize, data, symKey.data(), iv);
48 : }
49 :
50 4 : bool CBLSIESEncryptedBlob::Decrypt(const CBLSSecretKey& secretKey, CDataStream& decryptedDataRet) const
51 : {
52 4 : CBLSPublicKey pk;
53 4 : if (!pk.DHKeyExchange(secretKey, ephemeralPubKey)) {
54 : return false;
55 : }
56 :
57 8 : std::vector<unsigned char> symKey = pk.ToByteVector();
58 4 : symKey.resize(32);
59 :
60 4 : return DecryptBlob(data.data(), data.size(), decryptedDataRet, symKey.data(), iv);
61 : }
62 :
63 :
64 0 : bool CBLSIESMultiRecipientBlobs::Encrypt(const std::vector<CBLSPublicKey>& recipients, const BlobVector& _blobs)
65 : {
66 0 : if (recipients.size() != _blobs.size()) {
67 : return false;
68 : }
69 :
70 0 : InitEncrypt(_blobs.size());
71 :
72 0 : for (size_t i = 0; i < _blobs.size(); i++) {
73 0 : if (!Encrypt(i, recipients[i], _blobs[i])) {
74 : return false;
75 : }
76 : }
77 :
78 : return true;
79 : }
80 :
81 108 : void CBLSIESMultiRecipientBlobs::InitEncrypt(size_t count)
82 : {
83 108 : ephemeralSecretKey.MakeNewKey();
84 108 : ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
85 108 : GetStrongRandBytes(ivSeed.begin(), ivSeed.size());
86 :
87 108 : ivVector.resize(count);
88 108 : blobs.resize(count);
89 1912 : for (size_t i = 0; i < count; i++) {
90 1804 : ivVector[i] = (i == 0 ? ivSeed : ::SerializeHash(ivVector[i-1]));
91 : }
92 108 : }
93 :
94 1804 : bool CBLSIESMultiRecipientBlobs::Encrypt(size_t idx, const CBLSPublicKey& recipient, const Blob& blob)
95 : {
96 1804 : assert(idx < blobs.size());
97 :
98 1804 : CBLSPublicKey pk;
99 1804 : if (!pk.DHKeyExchange(ephemeralSecretKey, recipient)) {
100 : return false;
101 : }
102 :
103 3608 : std::vector<unsigned char> symKey = pk.ToByteVector();
104 1804 : symKey.resize(32);
105 :
106 1804 : return EncryptBlob(blob.data(), blob.size(), blobs[idx], symKey.data(), ivVector[idx].begin());
107 : }
108 :
109 1786 : bool CBLSIESMultiRecipientBlobs::Decrypt(size_t idx, const CBLSSecretKey& sk, Blob& blobRet) const
110 : {
111 1786 : if (idx >= blobs.size()) {
112 : return false;
113 : }
114 :
115 1786 : CBLSPublicKey pk;
116 1786 : if (!pk.DHKeyExchange(sk, ephemeralPubKey)) {
117 : return false;
118 : }
119 :
120 3572 : std::vector<unsigned char> symKey = pk.ToByteVector();
121 1786 : symKey.resize(32);
122 :
123 1786 : uint256 iv = ivSeed;
124 33172 : for (size_t i = 0; i < idx; i++) {
125 31386 : iv = ::SerializeHash(iv);
126 : }
127 :
128 1786 : return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin());
129 : }
|