LCOV - code coverage report
Current view: top level - src/sapling - zip32.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 79 90 87.8 %
Date: 2025-02-23 09:33:43 Functions: 10 12 83.3 %

          Line data    Source code
       1             : // Copyright (c) 2018-2020 The ZCash developers
       2             : // Copyright (c) 2021 The PIVX Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include "sapling/zip32.h"
       7             : 
       8             : #include "hash.h"
       9             : #include "random.h"
      10             : #include "sapling/prf.h"
      11             : #include "streams.h"
      12             : #include "version.h"
      13             : 
      14             : #include <librustzcash.h>
      15             : #include <sodium.h>
      16             : 
      17             : const unsigned char PIVX_HD_SEED_FP_PERSONAL[crypto_generichash_blake2b_PERSONALBYTES] =
      18             :     {'P', 'I', 'V', 'X', '_', '_', 'H', 'D', '_', 'S', 'e', 'e', 'd', '_', 'F', 'P'};
      19             : 
      20             : const unsigned char PIVX_TADDR_OVK_PERSONAL[crypto_generichash_blake2b_PERSONALBYTES] =
      21             :         {'P', 'x', 'T', 'a', 'd', 'd', 'r', 'T', 'o', 'S', 'a', 'p', 'l', 'i', 'n', 'g'};
      22             : 
      23           0 : HDSeed HDSeed::Random(size_t len)
      24             : {
      25           0 :     assert(len >= 32);
      26           0 :     CPrivKey rawSeed(len, 0);
      27           0 :     GetRandBytes(rawSeed.data(), len);
      28           0 :     return HDSeed(rawSeed);
      29             : }
      30             : 
      31           0 : uint256 HDSeed::Fingerprint() const
      32             : {
      33           0 :     CBLAKE2bWriter h(SER_GETHASH, 0, PIVX_HD_SEED_FP_PERSONAL);
      34           0 :     h << seed;
      35           0 :     return h.GetHash();
      36             : }
      37             : 
      38         241 : uint256 ovkForShieldingFromTaddr(HDSeed& seed) {
      39         241 :     auto rawSeed = seed.RawSeed();
      40             : 
      41             :     // I = BLAKE2b-512("ZcTaddrToSapling", seed)
      42         241 :     crypto_generichash_blake2b_state state;
      43         241 :     assert(crypto_generichash_blake2b_init_salt_personal(
      44             :             &state,
      45             :             nullptr, 0, // No key.
      46             :             64,
      47             :             nullptr,    // No salt.
      48             :             PIVX_TADDR_OVK_PERSONAL) == 0);
      49         241 :     crypto_generichash_blake2b_update(&state, rawSeed.data(), rawSeed.size());
      50         241 :     auto intermediate = std::array<unsigned char, 64>();
      51         241 :     crypto_generichash_blake2b_final(&state, intermediate.data(), 64);
      52             : 
      53             :     // I_L = I[0..32]
      54         241 :     uint256 intermediate_L;
      55         241 :     memcpy(intermediate_L.begin(), intermediate.data(), 32);
      56             : 
      57             :     // ovk = truncate_32(PRF^expand(I_L, [0x02]))
      58         482 :     return PRF_ovk(intermediate_L);
      59             : }
      60             : 
      61             : namespace libzcash {
      62             : 
      63           2 : Optional<SaplingExtendedFullViewingKey> SaplingExtendedFullViewingKey::Derive(uint32_t i) const
      64             : {
      65           4 :     CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
      66           2 :     ss_p << *this;
      67           4 :     CSerializeData p_bytes(ss_p.begin(), ss_p.end());
      68             : 
      69           4 :     CSerializeData i_bytes(ZIP32_XFVK_SIZE);
      70           2 :     if (librustzcash_zip32_xfvk_derive(
      71           2 :         reinterpret_cast<unsigned char*>(p_bytes.data()),
      72             :         i,
      73           2 :         reinterpret_cast<unsigned char*>(i_bytes.data())
      74             :     )) {
      75           2 :         CDataStream ss_i(i_bytes, SER_NETWORK, PROTOCOL_VERSION);
      76           1 :         SaplingExtendedFullViewingKey xfvk_i;
      77           1 :         ss_i >> xfvk_i;
      78           1 :         return xfvk_i;
      79             :     } else {
      80           1 :         return nullopt;
      81             :     }
      82             : }
      83             : 
      84             : Optional<std::pair<diversifier_index_t, libzcash::SaplingPaymentAddress>>
      85        7814 :     SaplingExtendedFullViewingKey::Address(diversifier_index_t j) const
      86             : {
      87       15628 :     CDataStream ss_xfvk(SER_NETWORK, PROTOCOL_VERSION);
      88        7814 :     ss_xfvk << *this;
      89       15628 :     CSerializeData xfvk_bytes(ss_xfvk.begin(), ss_xfvk.end());
      90             : 
      91        7814 :     diversifier_index_t j_ret;
      92       15628 :     CSerializeData addr_bytes(libzcash::SerializedSaplingPaymentAddressSize);
      93        7814 :     if (librustzcash_zip32_xfvk_address(
      94        7814 :         reinterpret_cast<unsigned char*>(xfvk_bytes.data()),
      95        7814 :         j.begin(), j_ret.begin(),
      96        7814 :         reinterpret_cast<unsigned char*>(addr_bytes.data()))) {
      97       15628 :         CDataStream ss_addr(addr_bytes, SER_NETWORK, PROTOCOL_VERSION);
      98        7814 :         libzcash::SaplingPaymentAddress addr;
      99        7814 :         ss_addr >> addr;
     100        7814 :         return std::make_pair(j_ret, addr);
     101             :     } else {
     102           0 :         return nullopt;
     103             :     }
     104             : }
     105             : 
     106        7812 : libzcash::SaplingPaymentAddress SaplingExtendedFullViewingKey::DefaultAddress() const
     107             : {
     108        7812 :     diversifier_index_t j0;
     109       15624 :     auto addr = Address(j0);
     110             :     // If we can't obtain a default address, we are *very* unlucky...
     111        7812 :     if (!addr) {
     112           0 :         throw std::runtime_error("SaplingExtendedFullViewingKey::DefaultAddress(): No valid diversifiers out of 2^88!");
     113             :     }
     114        7812 :     return addr.get().second;
     115             : }
     116             : 
     117        1267 : SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Master(const HDSeed& seed)
     118             : {
     119        1267 :     auto rawSeed = seed.RawSeed();
     120        2534 :     CSerializeData m_bytes(ZIP32_XSK_SIZE);
     121        1267 :     librustzcash_zip32_xsk_master(
     122        1267 :         rawSeed.data(),
     123             :         rawSeed.size(),
     124        1267 :         reinterpret_cast<unsigned char*>(m_bytes.data()));
     125             : 
     126        2534 :     CDataStream ss(m_bytes, SER_NETWORK, PROTOCOL_VERSION);
     127        1267 :     SaplingExtendedSpendingKey xsk_m;
     128        1267 :     ss >> xsk_m;
     129        2534 :     return xsk_m;
     130             : }
     131             : 
     132        6738 : SaplingExtendedSpendingKey SaplingExtendedSpendingKey::Derive(uint32_t i) const
     133             : {
     134        6738 :     CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
     135        6738 :     ss_p << *this;
     136       13476 :     CSerializeData p_bytes(ss_p.begin(), ss_p.end());
     137             : 
     138       13476 :     CSerializeData i_bytes(ZIP32_XSK_SIZE);
     139        6738 :     librustzcash_zip32_xsk_derive(
     140        6738 :         reinterpret_cast<unsigned char*>(p_bytes.data()),
     141             :         i,
     142        6738 :         reinterpret_cast<unsigned char*>(i_bytes.data()));
     143             : 
     144       13476 :     CDataStream ss_i(i_bytes, SER_NETWORK, PROTOCOL_VERSION);
     145        6738 :     SaplingExtendedSpendingKey xsk_i;
     146        6738 :     ss_i >> xsk_i;
     147       13476 :     return xsk_i;
     148             : }
     149             : 
     150       11068 : SaplingExtendedFullViewingKey SaplingExtendedSpendingKey::ToXFVK() const
     151             : {
     152       11068 :     SaplingExtendedFullViewingKey ret;
     153       11068 :     ret.depth = depth;
     154       11068 :     ret.parentFVKTag = parentFVKTag;
     155       11068 :     ret.childIndex = childIndex;
     156       11068 :     ret.chaincode = chaincode;
     157       11068 :     ret.fvk = expsk.full_viewing_key();
     158       11068 :     ret.dk = dk;
     159       11068 :     return ret;
     160             : }
     161             : 
     162        5394 : libzcash::SaplingPaymentAddress SaplingExtendedSpendingKey::DefaultAddress() const
     163             : {
     164        5394 :     return ToXFVK().DefaultAddress();
     165             : }
     166             : 
     167             : } // End namespace
     168             : 
     169        3940 : bool IsValidSpendingKey(const libzcash::SpendingKey& zkey) {
     170        3940 :     return zkey.which() != 0;
     171             : }
     172             : 
     173        1003 : bool IsValidViewingKey(const libzcash::ViewingKey& vk) {
     174        1003 :     return vk.which() != 0;
     175             : }

Generated by: LCOV version 1.14