Line data Source code
1 : // Copyright (c) 2018 The Dash Core developers
2 : // Copyright (c) 2021 The PIVX Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #ifndef PIVX_BLS_BLS_IES_H
7 : #define PIVX_BLS_BLS_IES_H
8 :
9 : #include "bls/bls_wrapper.h"
10 : #include "streams.h"
11 :
12 : // Base class to handle encryption/decryption of a binary object.
13 : // No padding: the size of the object must be a multiple of AES_BLOCKSIZE (16)
14 2 : class CBLSIESEncryptedBlob
15 : {
16 : public:
17 : CBLSPublicKey ephemeralPubKey;
18 : unsigned char iv[16];
19 : std::vector<unsigned char> data;
20 : bool valid{false};
21 :
22 : bool Encrypt(const CBLSPublicKey& peerPubKey, const void* data, size_t dataSize);
23 : bool Decrypt(const CBLSSecretKey& secretKey, CDataStream& decryptedDataRet) const;
24 :
25 : SERIALIZE_METHODS(CBLSIESEncryptedBlob, obj)
26 : {
27 : SER_WRITE(obj, assert(obj.valid));
28 :
29 : READWRITE(obj.ephemeralPubKey);
30 : READWRITE(obj.iv);
31 : READWRITE(obj.data);
32 :
33 : SER_READ(obj, obj.valid = true);
34 : }
35 : };
36 :
37 : // Encryption/Decryption of an object of type Object
38 : // (serialized size of Object must be multiple of AES_BLOCKSIZE)
39 : template <typename Object>
40 2 : class CBLSIESEncryptedObject : public CBLSIESEncryptedBlob
41 : {
42 : public:
43 1 : CBLSIESEncryptedObject()
44 1 : {
45 1 : }
46 :
47 2 : bool Encrypt(const CBLSPublicKey& peerPubKey, const Object& obj, int nVersion)
48 : {
49 : try {
50 4 : CDataStream ds(SER_NETWORK, nVersion);
51 2 : ds << obj;
52 2 : return CBLSIESEncryptedBlob::Encrypt(peerPubKey, ds.data(), ds.size());
53 0 : } catch (std::exception&) {
54 : return false;
55 : }
56 : }
57 :
58 4 : bool Decrypt(const CBLSSecretKey& secretKey, Object& objRet, int nVersion) const
59 : {
60 4 : CDataStream ds(SER_NETWORK, nVersion);
61 4 : if (!CBLSIESEncryptedBlob::Decrypt(secretKey, ds)) {
62 : return false;
63 : }
64 : try {
65 4 : ds >> objRet;
66 2 : } catch (std::exception& e) {
67 : return false;
68 : }
69 : return true;
70 : }
71 : };
72 :
73 : // Base class to handle encryption/decryption of a vector of binary objects.
74 : // No padding: the size of each object must be a multiple of AES_BLOCKSIZE (16)
75 : class CBLSIESMultiRecipientBlobs
76 : {
77 : public:
78 : typedef std::vector<unsigned char> Blob;
79 : typedef std::vector<Blob> BlobVector;
80 :
81 : public:
82 : CBLSPublicKey ephemeralPubKey;
83 : uint256 ivSeed;
84 : BlobVector blobs;
85 :
86 : // Used while encrypting. Temporary and only in-memory
87 : CBLSSecretKey ephemeralSecretKey;
88 : std::vector<uint256> ivVector;
89 :
90 : public:
91 : bool Encrypt(const std::vector<CBLSPublicKey>& recipients, const BlobVector& _blobs);
92 :
93 : void InitEncrypt(size_t count);
94 : bool Encrypt(size_t idx, const CBLSPublicKey& recipient, const Blob& blob);
95 : bool Decrypt(size_t idx, const CBLSSecretKey& sk, Blob& blobRet) const;
96 :
97 1509 : SERIALIZE_METHODS(CBLSIESMultiRecipientBlobs, obj)
98 : {
99 815 : READWRITE(obj.ephemeralPubKey);
100 815 : READWRITE(obj.ivSeed);
101 815 : READWRITE(obj.blobs);
102 815 : }
103 : };
104 :
105 : // Encryption/Decryption of a vector of objects of type Object
106 : // (the serialized size of Object must be multiple of AES_BLOCKSIZE)
107 : template <typename Object>
108 920 : class CBLSIESMultiRecipientObjects : public CBLSIESMultiRecipientBlobs
109 : {
110 : public:
111 : typedef std::vector<Object> ObjectVector;
112 :
113 : public:
114 : bool Encrypt(const std::vector<CBLSPublicKey>& recipients, const ObjectVector& _objects, int nVersion)
115 : {
116 : BlobVector blobs;
117 : blobs.resize(_objects.size());
118 :
119 : try {
120 : CDataStream ds(SER_NETWORK, nVersion);
121 : for (size_t i = 0; i < _objects.size(); i++) {
122 : ds.clear();
123 :
124 : ds << _objects[i];
125 : blobs[i].assign(ds.begin(), ds.end());
126 : }
127 : } catch (std::exception&) {
128 : return false;
129 : }
130 :
131 : return CBLSIESMultiRecipientBlobs::Encrypt(recipients, blobs);
132 : }
133 :
134 1804 : bool Encrypt(size_t idx, const CBLSPublicKey& recipient, const Object& obj, int nVersion)
135 : {
136 1804 : CDataStream ds(SER_NETWORK, nVersion);
137 3608 : ds << obj;
138 3608 : Blob blob(ds.begin(), ds.end());
139 3608 : return CBLSIESMultiRecipientBlobs::Encrypt(idx, recipient, blob);
140 : }
141 :
142 1786 : bool Decrypt(size_t idx, const CBLSSecretKey& sk, Object& objectRet, int nVersion) const
143 : {
144 1786 : Blob blob;
145 1786 : if (!CBLSIESMultiRecipientBlobs::Decrypt(idx, sk, blob)) {
146 : return false;
147 : }
148 :
149 : try {
150 3572 : CDataStream ds(blob, SER_NETWORK, nVersion);
151 1786 : ds >> objectRet;
152 1786 : return true;
153 0 : } catch (std::exception&) {
154 : return false;
155 : }
156 : }
157 : };
158 :
159 : #endif // PIVX_BLS_BLS_IES_H
|