Line data Source code
1 : // Copyright (c) 2018-2025 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 <hash.h>
8 : #include <random.h>
9 :
10 : #include <crypto/aes.h>
11 :
12 0 : static bool EncryptBlob(const void* in, size_t inSize, std::vector<unsigned char>& out, const void* symKey, const void* iv)
13 : {
14 0 : out.resize(inSize);
15 :
16 0 : AES256CBCEncrypt enc(reinterpret_cast<const unsigned char*>(symKey), reinterpret_cast<const unsigned char*>(iv), false);
17 0 : int w = enc.Encrypt(reinterpret_cast<const unsigned char*>(in), int(inSize), reinterpret_cast<unsigned char*>(out.data()));
18 0 : return w == int(inSize);
19 0 : }
20 :
21 : template <typename Out>
22 0 : static bool DecryptBlob(const void* in, size_t inSize, Out& out, const void* symKey, const void* iv)
23 : {
24 0 : out.resize(inSize);
25 :
26 0 : AES256CBCDecrypt enc(reinterpret_cast<const unsigned char*>(symKey), reinterpret_cast<const unsigned char*>(iv), false);
27 0 : int w = enc.Decrypt(reinterpret_cast<const unsigned char*>(in), int(inSize), reinterpret_cast<unsigned char*>(out.data()));
28 0 : return w == (int)inSize;
29 0 : }
30 :
31 0 : uint256 CBLSIESEncryptedBlob::GetIV(size_t idx) const
32 : {
33 0 : uint256 iv = ivSeed;
34 0 : for (size_t i = 0; i < idx; i++) {
35 0 : iv = ::SerializeHash(iv);
36 0 : }
37 0 : return iv;
38 : }
39 :
40 0 : bool CBLSIESEncryptedBlob::Decrypt(size_t idx, const CBLSSecretKey& secretKey, CDataStream& decryptedDataRet) const
41 : {
42 0 : CBLSPublicKey pk;
43 0 : if (!pk.DHKeyExchange(secretKey, ephemeralPubKey)) {
44 0 : return false;
45 : }
46 :
47 0 : std::vector<unsigned char> symKey = pk.ToByteVector(false);
48 0 : symKey.resize(32);
49 :
50 0 : uint256 iv = GetIV(idx);
51 0 : return DecryptBlob(data.data(), data.size(), decryptedDataRet, symKey.data(), iv.begin());
52 0 : }
53 :
54 0 : bool CBLSIESEncryptedBlob::IsValid() const
55 : {
56 0 : return ephemeralPubKey.IsValid() && !data.empty() && !ivSeed.IsNull();
57 : }
58 :
59 0 : void CBLSIESMultiRecipientBlobs::InitEncrypt(size_t count)
60 : {
61 0 : ephemeralSecretKey.MakeNewKey();
62 0 : ephemeralPubKey = ephemeralSecretKey.GetPublicKey();
63 0 : GetStrongRandBytes({ivSeed.begin(), ivSeed.size()});
64 :
65 0 : uint256 iv = ivSeed;
66 0 : ivVector.resize(count);
67 0 : blobs.resize(count);
68 0 : for (size_t i = 0; i < count; i++) {
69 0 : ivVector[i] = iv;
70 0 : iv = ::SerializeHash(iv);
71 0 : }
72 0 : }
73 :
74 0 : bool CBLSIESMultiRecipientBlobs::Encrypt(size_t idx, const CBLSPublicKey& recipient, const Blob& blob)
75 : {
76 0 : assert(idx < blobs.size());
77 :
78 0 : CBLSPublicKey pk;
79 0 : if (!pk.DHKeyExchange(ephemeralSecretKey, recipient)) {
80 0 : return false;
81 : }
82 :
83 0 : std::vector<uint8_t> symKey = pk.ToByteVector(false);
84 0 : symKey.resize(32);
85 :
86 0 : return EncryptBlob(blob.data(), blob.size(), blobs[idx], symKey.data(), ivVector[idx].begin());
87 0 : }
88 :
89 0 : bool CBLSIESMultiRecipientBlobs::Decrypt(size_t idx, const CBLSSecretKey& sk, Blob& blobRet) const
90 : {
91 0 : if (idx >= blobs.size()) {
92 0 : return false;
93 : }
94 :
95 0 : CBLSPublicKey pk;
96 0 : if (!pk.DHKeyExchange(sk, ephemeralPubKey)) {
97 0 : return false;
98 : }
99 :
100 0 : std::vector<uint8_t> symKey = pk.ToByteVector(false);
101 0 : symKey.resize(32);
102 :
103 0 : uint256 iv = ivSeed;
104 0 : for (size_t i = 0; i < idx; i++) {
105 0 : iv = ::SerializeHash(iv);
106 0 : }
107 :
108 0 : return DecryptBlob(blobs[idx].data(), blobs[idx].size(), blobRet, symKey.data(), iv.begin());
109 0 : }
|