PIVX Core  5.6.99
P2P Digital Currency
prf.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016-2020 The ZCash developers
2 // Copyright (c) 2020 The PIVX Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 
7 #include "prf.h"
8 #include "crypto/sha256.h"
9 #include "hash.h"
10 
11 #include <array>
12 #include <sodium.h>
13 #include <librustzcash.h>
14 
15 const unsigned char ZCASH_EXPANDSEED_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] = {'Z','c','a','s','h','_','E','x','p','a','n','d','S','e','e','d'};
16 
17 // Sapling
18 std::array<unsigned char, 64> PRF_expand(const uint256& sk, unsigned char t)
19 {
20  std::array<unsigned char, 64> res;
21  unsigned char blob[33];
22 
23  memcpy(&blob[0], sk.begin(), 32);
24  blob[32] = t;
25 
26  crypto_generichash_blake2b_state state;
27  crypto_generichash_blake2b_init_salt_personal(&state, nullptr, 0, 64, nullptr, ZCASH_EXPANDSEED_PERSONALIZATION);
28  crypto_generichash_blake2b_update(&state, blob, 33);
29  crypto_generichash_blake2b_final(&state, res.data(), 64);
30 
31  return res;
32 }
33 
35 {
36  uint256 ask;
37  auto tmp = PRF_expand(sk, 0);
38  librustzcash_to_scalar(tmp.data(), ask.begin());
39  return ask;
40 }
41 
43 {
44  uint256 nsk;
45  auto tmp = PRF_expand(sk, 1);
46  librustzcash_to_scalar(tmp.data(), nsk.begin());
47  return nsk;
48 }
49 
51 {
52  uint256 ovk;
53  auto tmp = PRF_expand(sk, 2);
54  memcpy(ovk.begin(), tmp.data(), 32);
55  return ovk;
56 }
57 
58 std::array<unsigned char, 11> default_diversifier(const uint256& sk)
59 {
60  std::array<unsigned char, 11> res;
61  unsigned char blob[34];
62 
63  memcpy(&blob[0], sk.begin(), 32);
64  blob[32] = 3;
65 
66  blob[33] = 0;
67  while (true) {
68  crypto_generichash_blake2b_state state;
69  crypto_generichash_blake2b_init_salt_personal(&state, nullptr, 0, 64, nullptr, ZCASH_EXPANDSEED_PERSONALIZATION);
70  crypto_generichash_blake2b_update(&state, blob, 34);
71  crypto_generichash_blake2b_final(&state, res.data(), 11);
72 
73  if (librustzcash_check_diversifier(res.data())) {
74  break;
75  } else if (blob[33] == 255) {
76  throw std::runtime_error("librustzcash_check_diversifier did not return valid diversifier");
77  }
78  blob[33] += 1;
79  }
80 
81  return res;
82 }
unsigned char * begin()
Definition: uint256.h:63
256-bit opaque blob.
Definition: uint256.h:138
void * memcpy(void *a, const void *b, size_t c)
bool librustzcash_check_diversifier(const unsigned char *diversifier)
void librustzcash_to_scalar(const unsigned char *input, unsigned char *result)
const unsigned char ZCASH_EXPANDSEED_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES]
Definition: prf.cpp:15
uint256 PRF_ovk(const uint256 &sk)
Definition: prf.cpp:50
uint256 PRF_ask(const uint256 &sk)
Sapling functions.
Definition: prf.cpp:34
uint256 PRF_nsk(const uint256 &sk)
Definition: prf.cpp:42
std::array< unsigned char, 11 > default_diversifier(const uint256 &sk)
Definition: prf.cpp:58
std::array< unsigned char, 64 > PRF_expand(const uint256 &sk, unsigned char t)
Definition: prf.cpp:18