Skip to content

Commit fe08568

Browse files
committed
[Sapling] prf integrated.
1 parent 72dfdfa commit fe08568

File tree

6 files changed

+224
-8
lines changed

6 files changed

+224
-8
lines changed

configure.ac

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,8 @@ else
11331133
fi
11341134
fi
11351135

1136+
LIBSAPLING_LIBS="-lgmp -lboost_system-mt -lcrypto -lsodium"
1137+
11361138
dnl univalue check
11371139

11381140
need_bundled_univalue=yes
@@ -1187,7 +1189,7 @@ BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path)
11871189
AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing],[CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"])
11881190
AX_CHECK_COMPILE_FLAG([-Wno-builtin-declaration-mismatch],[CXXFLAGS="$CXXFLAGS -Wno-builtin-declaration-mismatch"],,[[$CXXFLAG_WERROR]])
11891191

1190-
LIBZCASH_LIBS="$BOOST_SYSTEM_LIB -lcrypto -lrustzcash"
1192+
LIBZCASH_LIBS="$BOOST_SYSTEM_LIB -lcrypto -lsodium -lrustzcash"
11911193

11921194
AC_MSG_CHECKING([whether to build pivxd])
11931195
AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes])
@@ -1438,6 +1440,7 @@ AC_SUBST(SSL_LIBS)
14381440
AC_SUBST(EVENT_LIBS)
14391441
AC_SUBST(EVENT_PTHREADS_LIBS)
14401442
AC_SUBST(ZMQ_LIBS)
1443+
AC_SUBST(LIBSAPLING_LIBS)
14411444
AC_SUBST(LIBZCASH_LIBS)
14421445
AC_SUBST(PROTOBUF_LIBS)
14431446
AC_SUBST(QR_LIBS)

src/Makefile.am

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
3333
LIBBITCOIN_ZEROCOIN=libzerocoin/libbitcoin_zerocoin.a
3434
LIBBITCOINQT=qt/libbitcoinqt.a
3535
LIBSECP256K1=secp256k1/libsecp256k1.la
36+
LIBSAPLING=libsapling.a
3637

3738
if ENABLE_ZMQ
3839
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
@@ -57,7 +58,8 @@ EXTRA_LIBRARIES += \
5758
$(LIBBITCOIN_SERVER) \
5859
$(LIBBITCOIN_CLI) \
5960
$(LIBBITCOIN_WALLET) \
60-
$(LIBBITCOIN_ZMQ)
61+
$(LIBBITCOIN_ZMQ) \
62+
$(LIBSAPLING)
6163

6264
lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
6365

@@ -74,6 +76,9 @@ if BUILD_BITCOIN_UTILS
7476
bin_PROGRAMS += pivx-cli pivx-tx
7577
endif
7678

79+
LIBSAPLING_H = \
80+
sapling/prf.h
81+
7782
.PHONY: FORCE check-symbols check-security
7883
# pivx core #
7984
BITCOIN_CORE_H = \
@@ -188,6 +193,7 @@ BITCOIN_CORE_H = \
188193
guiinterface.h \
189194
guiinterfaceutil.h \
190195
uint256.h \
196+
sapling/uint252.h \
191197
uint512.h \
192198
blob_uint256.h \
193199
undo.h \
@@ -267,7 +273,8 @@ libbitcoin_server_a_SOURCES = \
267273
txmempool.cpp \
268274
validationinterface.cpp \
269275
zpivchain.cpp \
270-
$(BITCOIN_CORE_H)
276+
$(BITCOIN_CORE_H) \
277+
$(LIBSAPLING_H)
271278

272279
if ENABLE_ZMQ
273280
libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
@@ -317,7 +324,8 @@ libbitcoin_wallet_a_SOURCES = \
317324
stakeinput.cpp \
318325
zpiv/zpivmodule.cpp \
319326
zpiv/zpos.cpp \
320-
$(BITCOIN_CORE_H)
327+
$(BITCOIN_CORE_H) \
328+
$(LIBSAPLING_H)
321329

322330
# crypto primitives library
323331
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIC_FLAGS)
@@ -424,7 +432,8 @@ libbitcoin_common_a_SOURCES = \
424432
script/script_error.cpp \
425433
spork.cpp \
426434
sporkdb.cpp \
427-
$(BITCOIN_CORE_H)
435+
$(BITCOIN_CORE_H) \
436+
$(LIBSAPLING_H)
428437

429438
# util: shared between all executables.
430439
# This library *must* be included to make sure that the glibc
@@ -452,7 +461,8 @@ libbitcoin_util_a_SOURCES = \
452461
util/threadnames.cpp \
453462
utilstrencodings.cpp \
454463
utiltime.cpp \
455-
$(BITCOIN_CORE_H)
464+
$(BITCOIN_CORE_H) \
465+
$(LIBSAPLING_H)
456466

457467
if GLIBC_BACK_COMPAT
458468
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
@@ -464,7 +474,8 @@ libbitcoin_cli_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
464474
libbitcoin_cli_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
465475
libbitcoin_cli_a_SOURCES = \
466476
rpc/client.cpp \
467-
$(BITCOIN_CORE_H)
477+
$(BITCOIN_CORE_H) \
478+
$(LIBSAPLING_H)
468479

469480
nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
470481
#
@@ -487,6 +498,7 @@ pivxd_LDADD = \
487498
$(LIBBITCOIN_UTIL) \
488499
$(LIBBITCOIN_ZMQ) \
489500
$(LIBBITCOIN_CRYPTO) \
501+
$(LIBSAPLING) \
490502
$(LIBLEVELDB) \
491503
$(LIBLEVELDB_SSE42) \
492504
$(LIBMEMENV) \
@@ -510,6 +522,7 @@ pivx_cli_LDADD = \
510522
$(LIBUNIVALUE) \
511523
$(LIBBITCOIN_UTIL) \
512524
$(LIBBITCOIN_CRYPTO) \
525+
$(LIBSAPLING) \
513526
$(LIBZCASH_LIBS)
514527

515528
pivx_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS)
@@ -532,11 +545,18 @@ pivx_tx_LDADD = \
532545
$(LIBBITCOIN_UTIL) \
533546
$(LIBBITCOIN_CRYPTO) \
534547
$(LIBSECP256K1) \
548+
$(LIBSAPLING) \
535549
$(LIBZCASH_LIBS)
536550

537551
pivx_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS)
538552
#
539553

554+
# sapling protocol primitives #
555+
libsapling_a_SOURCES = \
556+
sapling/prf.cpp
557+
558+
libsapling_a_CPPFLAGS = -fPIC -DCURVE_ALT_BN128 -DBOOST_SPIRIT_THREADSAFE -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -std=c++11 -pipe -O2 -O0 -g -Wstack-protector -fstack-protector-all -fPIE -fvisibility=hidden -DSTATIC $(BITCOIN_INCLUDES)
559+
540560
# bitcoinconsensus library #
541561
if BUILD_BITCOIN_LIBS
542562
include_HEADERS = script/bitcoinconsensus.h

src/Makefile.test.include

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ BITCOIN_TESTS =\
8484
test/uint256_tests.cpp \
8585
test/univalue_tests.cpp \
8686
test/util_tests.cpp \
87+
test/sha256compress_tests.cpp \
8788
test/upgrades_tests.cpp
8889

8990
if ENABLE_WALLET
@@ -96,7 +97,7 @@ endif
9697
test_test_pivx_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
9798
test_test_pivx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_FLAGS)
9899
test_test_pivx_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBBITCOIN_ZEROCOIN) \
99-
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
100+
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(LIBSAPLING) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
100101
if ENABLE_WALLET
101102
test_test_pivx_LDADD += $(LIBBITCOIN_WALLET)
102103
endif

src/sapling/prf.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) 2016-2020 The ZCash developers
2+
// Copyright (c) 2020 The PIVX 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+
34+
uint256 PRF_ask(const uint256& sk)
35+
{
36+
uint256 ask;
37+
auto tmp = PRF_expand(sk, 0);
38+
librustzcash_to_scalar(tmp.data(), ask.begin());
39+
return ask;
40+
}
41+
42+
uint256 PRF_nsk(const uint256& sk)
43+
{
44+
uint256 nsk;
45+
auto tmp = PRF_expand(sk, 1);
46+
librustzcash_to_scalar(tmp.data(), nsk.begin());
47+
return nsk;
48+
}
49+
50+
uint256 PRF_ovk(const uint256& sk)
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+
}
83+
84+
// Sprout
85+
uint256 PRF(bool a, bool b, bool c, bool d,
86+
const uint252& x,
87+
const uint256& y)
88+
{
89+
uint256 res;
90+
unsigned char blob[64];
91+
92+
memcpy(&blob[0], x.begin(), 32);
93+
memcpy(&blob[32], y.begin(), 32);
94+
95+
blob[0] &= 0x0F;
96+
blob[0] |= (a ? 1 << 7 : 0) | (b ? 1 << 6 : 0) | (c ? 1 << 5 : 0) | (d ? 1 << 4 : 0);
97+
98+
CSHA256 hasher;
99+
hasher.Write(blob, 64);
100+
hasher.FinalizeNoPadding(res.begin());
101+
102+
return res;
103+
}
104+
105+
uint256 PRF_addr(const uint252& a_sk, unsigned char t)
106+
{
107+
uint256 y;
108+
*(y.begin()) = t;
109+
110+
return PRF(1, 1, 0, 0, a_sk, y);
111+
}

src/sapling/prf.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2016-2020 The ZCash developers
2+
// Copyright (c) 2020 The PIVX 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+
// Zcash uses SHA256Compress as a PRF for various components
8+
// within the zkSNARK circuit.
9+
*/
10+
11+
#ifndef ZC_PRF_H_
12+
#define ZC_PRF_H_
13+
14+
#include "uint256.h"
15+
#include "sapling/uint252.h"
16+
17+
#include <array>
18+
19+
//! Sapling functions
20+
uint256 PRF_ask(const uint256& sk);
21+
uint256 PRF_nsk(const uint256& sk);
22+
uint256 PRF_ovk(const uint256& sk);
23+
24+
std::array<unsigned char, 11> default_diversifier(const uint256& sk);
25+
26+
#endif // ZC_PRF_H_

src/sapling/uint252.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2016-2020 The ZCash developers
2+
// Copyright (c) 2020 The PIVX 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+
#ifndef UINT252_H
7+
#define UINT252_H
8+
9+
#include <vector>
10+
#include "uint256.h"
11+
#include "serialize.h"
12+
13+
// Wrapper of uint256 with guarantee that first
14+
// four bits are zero.
15+
class uint252 {
16+
private:
17+
uint256 contents;
18+
19+
public:
20+
ADD_SERIALIZE_METHODS;
21+
22+
template <typename Stream, typename Operation>
23+
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
24+
READWRITE(contents);
25+
26+
if ((*contents.begin()) & 0xF0) {
27+
throw std::ios_base::failure("spending key has invalid leading bits");
28+
}
29+
}
30+
31+
const unsigned char* begin() const
32+
{
33+
return contents.begin();
34+
}
35+
36+
const unsigned char* end() const
37+
{
38+
return contents.end();
39+
}
40+
41+
uint252() : contents() {};
42+
explicit uint252(const uint256& in) : contents(in) {
43+
if (*contents.begin() & 0xF0) {
44+
throw std::domain_error("leading bits are set in argument given to uint252 constructor");
45+
}
46+
}
47+
48+
uint256 inner() const {
49+
return contents;
50+
}
51+
52+
friend inline bool operator==(const uint252& a, const uint252& b) { return a.contents == b.contents; }
53+
};
54+
55+
#endif

0 commit comments

Comments
 (0)