LCOV - code coverage report
Current view: top level - src/bls - bls_ies.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 58 64 90.6 %
Date: 2026-06-25 07:23:43 Functions: 8 9 88.9 %

          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 : }

Generated by: LCOV version 1.16