Line data Source code
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 427 : std::array<unsigned char, 64> PRF_expand(const uint256& sk, unsigned char t)
19 : {
20 427 : std::array<unsigned char, 64> res;
21 427 : unsigned char blob[33];
22 :
23 427 : memcpy(&blob[0], sk.begin(), 32);
24 427 : blob[32] = t;
25 :
26 427 : crypto_generichash_blake2b_state state;
27 427 : crypto_generichash_blake2b_init_salt_personal(&state, nullptr, 0, 64, nullptr, ZCASH_EXPANDSEED_PERSONALIZATION);
28 427 : crypto_generichash_blake2b_update(&state, blob, 33);
29 427 : crypto_generichash_blake2b_final(&state, res.data(), 64);
30 :
31 427 : return res;
32 : }
33 :
34 62 : uint256 PRF_ask(const uint256& sk)
35 : {
36 62 : uint256 ask;
37 62 : auto tmp = PRF_expand(sk, 0);
38 62 : librustzcash_to_scalar(tmp.data(), ask.begin());
39 62 : return ask;
40 : }
41 :
42 62 : uint256 PRF_nsk(const uint256& sk)
43 : {
44 62 : uint256 nsk;
45 62 : auto tmp = PRF_expand(sk, 1);
46 62 : librustzcash_to_scalar(tmp.data(), nsk.begin());
47 62 : return nsk;
48 : }
49 :
50 303 : uint256 PRF_ovk(const uint256& sk)
51 : {
52 303 : uint256 ovk;
53 303 : auto tmp = PRF_expand(sk, 2);
54 303 : memcpy(ovk.begin(), tmp.data(), 32);
55 303 : return ovk;
56 : }
57 :
58 18 : std::array<unsigned char, 11> default_diversifier(const uint256& sk)
59 : {
60 18 : std::array<unsigned char, 11> res;
61 18 : unsigned char blob[34];
62 :
63 18 : memcpy(&blob[0], sk.begin(), 32);
64 18 : blob[32] = 3;
65 :
66 18 : blob[33] = 0;
67 48 : while (true) {
68 33 : crypto_generichash_blake2b_state state;
69 33 : crypto_generichash_blake2b_init_salt_personal(&state, nullptr, 0, 64, nullptr, ZCASH_EXPANDSEED_PERSONALIZATION);
70 33 : crypto_generichash_blake2b_update(&state, blob, 34);
71 33 : crypto_generichash_blake2b_final(&state, res.data(), 11);
72 :
73 33 : if (librustzcash_check_diversifier(res.data())) {
74 : break;
75 15 : } else if (blob[33] == 255) {
76 0 : throw std::runtime_error("librustzcash_check_diversifier did not return valid diversifier");
77 : }
78 15 : blob[33] += 1;
79 15 : }
80 :
81 18 : return res;
82 : }
|