PIVX Core  5.6.99
P2P Digital Currency
zip32.cpp
Go to the documentation of this file.
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 
24 {
25  assert(len >= 32);
26  CPrivKey rawSeed(len, 0);
27  GetRandBytes(rawSeed.data(), len);
28  return HDSeed(rawSeed);
29 }
30 
32 {
34  h << seed;
35  return h.GetHash();
36 }
37 
39  auto rawSeed = seed.RawSeed();
40 
41  // I = BLAKE2b-512("ZcTaddrToSapling", seed)
42  crypto_generichash_blake2b_state state;
43  assert(crypto_generichash_blake2b_init_salt_personal(
44  &state,
45  nullptr, 0, // No key.
46  64,
47  nullptr, // No salt.
49  crypto_generichash_blake2b_update(&state, rawSeed.data(), rawSeed.size());
50  auto intermediate = std::array<unsigned char, 64>();
51  crypto_generichash_blake2b_final(&state, intermediate.data(), 64);
52 
53  // I_L = I[0..32]
54  uint256 intermediate_L;
55  memcpy(intermediate_L.begin(), intermediate.data(), 32);
56 
57  // ovk = truncate_32(PRF^expand(I_L, [0x02]))
58  return PRF_ovk(intermediate_L);
59 }
60 
61 namespace libzcash {
62 
64 {
65  CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
66  ss_p << *this;
67  CSerializeData p_bytes(ss_p.begin(), ss_p.end());
68 
71  reinterpret_cast<unsigned char*>(p_bytes.data()),
72  i,
73  reinterpret_cast<unsigned char*>(i_bytes.data())
74  )) {
75  CDataStream ss_i(i_bytes, SER_NETWORK, PROTOCOL_VERSION);
77  ss_i >> xfvk_i;
78  return xfvk_i;
79  } else {
80  return nullopt;
81  }
82 }
83 
86 {
87  CDataStream ss_xfvk(SER_NETWORK, PROTOCOL_VERSION);
88  ss_xfvk << *this;
89  CSerializeData xfvk_bytes(ss_xfvk.begin(), ss_xfvk.end());
90 
91  diversifier_index_t j_ret;
94  reinterpret_cast<unsigned char*>(xfvk_bytes.data()),
95  j.begin(), j_ret.begin(),
96  reinterpret_cast<unsigned char*>(addr_bytes.data()))) {
97  CDataStream ss_addr(addr_bytes, SER_NETWORK, PROTOCOL_VERSION);
99  ss_addr >> addr;
100  return std::make_pair(j_ret, addr);
101  } else {
102  return nullopt;
103  }
104 }
105 
107 {
109  auto addr = Address(j0);
110  // If we can't obtain a default address, we are *very* unlucky...
111  if (!addr) {
112  throw std::runtime_error("SaplingExtendedFullViewingKey::DefaultAddress(): No valid diversifiers out of 2^88!");
113  }
114  return addr.get().second;
115 }
116 
118 {
119  auto rawSeed = seed.RawSeed();
122  rawSeed.data(),
123  rawSeed.size(),
124  reinterpret_cast<unsigned char*>(m_bytes.data()));
125 
126  CDataStream ss(m_bytes, SER_NETWORK, PROTOCOL_VERSION);
128  ss >> xsk_m;
129  return xsk_m;
130 }
131 
133 {
134  CDataStream ss_p(SER_NETWORK, PROTOCOL_VERSION);
135  ss_p << *this;
136  CSerializeData p_bytes(ss_p.begin(), ss_p.end());
137 
140  reinterpret_cast<unsigned char*>(p_bytes.data()),
141  i,
142  reinterpret_cast<unsigned char*>(i_bytes.data()));
143 
144  CDataStream ss_i(i_bytes, SER_NETWORK, PROTOCOL_VERSION);
146  ss_i >> xsk_i;
147  return xsk_i;
148 }
149 
151 {
153  ret.depth = depth;
155  ret.childIndex = childIndex;
156  ret.chaincode = chaincode;
157  ret.fvk = expsk.full_viewing_key();
158  ret.dk = dk;
159  return ret;
160 }
161 
163 {
164  return ToXFVK().DefaultAddress();
165 }
166 
167 } // End namespace
168 
170  return zkey.which() != 0;
171 }
172 
174  return vk.which() != 0;
175 }
A writer stream (for serialization) that computes a 256-bit BLAKE2b hash.
Definition: hash.h:298
uint256 GetHash()
Definition: hash.h:321
const_iterator end() const
Definition: streams.h:163
const_iterator begin() const
Definition: streams.h:161
Definition: zip32.h:20
uint256 Fingerprint() const
Definition: zip32.cpp:31
CPrivKey RawSeed() const
Definition: zip32.h:31
CPrivKey seed
Definition: zip32.h:22
HDSeed()
Definition: zip32.h:25
static HDSeed Random(size_t len=32)
Definition: zip32.cpp:23
unsigned char * begin()
Definition: uint256.h:63
88-bit opaque blob.
Definition: uint256.h:116
SaplingFullViewingKey full_viewing_key() const
Definition: address.cpp:29
Sapling functions.
Definition: address.h:30
256-bit opaque blob.
Definition: uint256.h:138
void * memcpy(void *a, const void *b, size_t c)
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (PRIVATE_KEY_SIZE bytes)
Definition: key.h:20
bool librustzcash_zip32_xfvk_address(const unsigned char *xfvk, const unsigned char *j, unsigned char *j_ret, unsigned char *addr_ret)
Derive a PaymentAddress from an ExtendedFullViewingKey.
void librustzcash_zip32_xsk_master(const unsigned char *seed, size_t seedlen, unsigned char *xsk_master)
Derive the master ExtendedSpendingKey from a seed.
void librustzcash_zip32_xsk_derive(const unsigned char *xsk_parent, uint32_t i, unsigned char *xsk_i)
Derive a child ExtendedSpendingKey from a parent.
bool librustzcash_zip32_xfvk_derive(const unsigned char *xfvk_parent, uint32_t i, unsigned char *xfvk_i)
Derive a child ExtendedFullViewingKey from a parent.
const size_t SerializedSaplingPaymentAddressSize
Definition: address.h:24
boost::variant< InvalidEncoding, SaplingExtendedSpendingKey > SpendingKey
Definition: zip32.h:116
boost::variant< InvalidEncoding, SaplingExtendedFullViewingKey > ViewingKey
Definition: zip32.h:117
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
uint256 PRF_ovk(const uint256 &sk)
Definition: prf.cpp:50
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:579
@ SER_NETWORK
Definition: serialize.h:174
@ SER_GETHASH
Definition: serialize.h:176
Optional< std::pair< diversifier_index_t, libzcash::SaplingPaymentAddress > > Address(diversifier_index_t j) const
Definition: zip32.cpp:85
libzcash::SaplingFullViewingKey fvk
Definition: zip32.h:56
Optional< SaplingExtendedFullViewingKey > Derive(uint32_t i) const
Definition: zip32.cpp:63
libzcash::SaplingPaymentAddress DefaultAddress() const
Definition: zip32.cpp:106
libzcash::SaplingExpandedSpendingKey expsk
Definition: zip32.h:92
libzcash::SaplingPaymentAddress DefaultAddress() const
Definition: zip32.cpp:162
SaplingExtendedSpendingKey Derive(uint32_t i) const
Definition: zip32.cpp:132
static SaplingExtendedSpendingKey Master(const HDSeed &seed)
Definition: zip32.cpp:117
SaplingExtendedFullViewingKey ToXFVK() const
Definition: zip32.cpp:150
std::vector< char, zero_after_free_allocator< char > > CSerializeData
Definition: zeroafterfree.h:46
const unsigned char PIVX_HD_SEED_FP_PERSONAL[crypto_generichash_blake2b_PERSONALBYTES]
Definition: zip32.cpp:17
const unsigned char PIVX_TADDR_OVK_PERSONAL[crypto_generichash_blake2b_PERSONALBYTES]
Definition: zip32.cpp:20
bool IsValidSpendingKey(const libzcash::SpendingKey &zkey)
Check whether a SpendingKey is not an InvalidEncoding.
Definition: zip32.cpp:169
bool IsValidViewingKey(const libzcash::ViewingKey &vk)
Check whether a ViewingKey is not an InvalidEncoding.
Definition: zip32.cpp:173
uint256 ovkForShieldingFromTaddr(HDSeed &seed)
Definition: zip32.cpp:38
const size_t ZIP32_XFVK_SIZE
Definition: zip32.h:17
const size_t ZIP32_XSK_SIZE
Definition: zip32.h:18