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