Auto merge of #3326 - str4d:3058-sapling-addresses, r=str4d

Sapling address encodings

This PR enables Sapling keys and addresses to be passed in anywhere Sprout keys
and addresses are used. Doing so will cause crashes until those places are updated
with Sapling support.

Includes code cherry-picked from the following upstream PRs:

- bitcoin/bitcoin#11167
  - Only the `ConvertBits()` function.
- bitcoin/bitcoin#11630

Closes #3058.
This commit is contained in:
Homu
2018-06-19 05:12:50 -07:00
13 changed files with 303 additions and 249 deletions

View File

@@ -16,9 +16,9 @@ BOOST_AUTO_TEST_CASE(base32_testvectors)
for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::string strEnc = EncodeBase32(vstrIn[i]);
BOOST_CHECK(strEnc == vstrOut[i]);
BOOST_CHECK_EQUAL(strEnc, vstrOut[i]);
std::string strDec = DecodeBase32(vstrOut[i]);
BOOST_CHECK(strDec == vstrIn[i]);
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
}
}

View File

@@ -16,9 +16,9 @@ BOOST_AUTO_TEST_CASE(base64_testvectors)
for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::string strEnc = EncodeBase64(vstrIn[i]);
BOOST_CHECK(strEnc == vstrOut[i]);
BOOST_CHECK_EQUAL(strEnc, vstrOut[i]);
std::string strDec = DecodeBase64(strEnc);
BOOST_CHECK(strDec == vstrIn[i]);
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
}
}

View File

@@ -64,4 +64,37 @@ BOOST_AUTO_TEST_CASE(bip173_testvectors_invalid)
}
}
BOOST_AUTO_TEST_CASE(bech32_deterministic_valid)
{
for (size_t i = 0; i < 255; i++) {
std::vector<unsigned char> input(32, i);
auto encoded = bech32::Encode("a", input);
if (i < 32) {
// Valid input
BOOST_CHECK(!encoded.empty());
auto ret = bech32::Decode(encoded);
BOOST_CHECK(ret.first == "a");
BOOST_CHECK(ret.second == input);
} else {
// Invalid input
BOOST_CHECK(encoded.empty());
}
}
for (size_t i = 0; i < 255; i++) {
std::vector<unsigned char> input(43, i);
auto encoded = bech32::Encode("a", input);
if (i < 32) {
// Valid input
BOOST_CHECK(!encoded.empty());
auto ret = bech32::Decode(encoded);
BOOST_CHECK(ret.first == "a");
BOOST_CHECK(ret.second == input);
} else {
// Invalid input
BOOST_CHECK(encoded.empty());
}
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2018 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <utilstrencodings.h>
#include <test/test_bitcoin.h>
#include <zcash/NoteEncryption.hpp>
#include <boost/test/unit_test.hpp>
BOOST_FIXTURE_TEST_SUITE(convertbits_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(convertbits_deterministic)
{
for (size_t i = 0; i < 256; i++) {
std::vector<unsigned char> input(32, i);
std::vector<unsigned char> data;
std::vector<unsigned char> output;
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, input.begin(), input.end());
ConvertBits<5, 8, false>([&](unsigned char c) { output.push_back(c); }, data.begin(), data.end());
BOOST_CHECK_EQUAL(data.size(), 52);
BOOST_CHECK_EQUAL(output.size(), 32);
BOOST_CHECK(input == output);
}
for (size_t i = 0; i < 256; i++) {
std::vector<unsigned char> input(43, i);
std::vector<unsigned char> data;
std::vector<unsigned char> output;
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, input.begin(), input.end());
ConvertBits<5, 8, false>([&](unsigned char c) { output.push_back(c); }, data.begin(), data.end());
BOOST_CHECK_EQUAL(data.size(), 69);
BOOST_CHECK_EQUAL(output.size(), 43);
BOOST_CHECK(input == output);
}
}
BOOST_AUTO_TEST_CASE(convertbits_random)
{
for (size_t i = 0; i < 1000; i++) {
auto input = libzcash::random_uint256();
std::vector<unsigned char> data;
std::vector<unsigned char> output;
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, input.begin(), input.end());
ConvertBits<5, 8, false>([&](unsigned char c) { output.push_back(c); }, data.begin(), data.end());
BOOST_CHECK_EQUAL(data.size(), 52);
BOOST_CHECK_EQUAL(output.size(), 32);
BOOST_CHECK(input == uint256(output));
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -4,6 +4,7 @@
#include "key.h"
#include "chainparams.h"
#include "key_io.h"
#include "script/script.h"
#include "uint256.h"
@@ -220,4 +221,35 @@ BOOST_AUTO_TEST_CASE(zc_address_test)
}
}
BOOST_AUTO_TEST_CASE(zs_address_test)
{
for (size_t i = 0; i < 1000; i++) {
auto sk = SaplingSpendingKey::random();
{
std::string sk_string = EncodeSpendingKey(sk);
BOOST_CHECK(sk_string.compare(0, 24, Params().Bech32HRP(CChainParams::SAPLING_SPENDING_KEY)) == 0);
auto spendingkey2 = DecodeSpendingKey(sk_string);
BOOST_CHECK(IsValidSpendingKey(spendingkey2));
BOOST_ASSERT(boost::get<SaplingSpendingKey>(&spendingkey2) != nullptr);
auto sk2 = boost::get<SaplingSpendingKey>(spendingkey2);
BOOST_CHECK(sk == sk2);
}
{
auto addr = sk.default_address();
std::string addr_string = EncodePaymentAddress(*addr);
BOOST_CHECK(addr_string.compare(0, 2, Params().Bech32HRP(CChainParams::SAPLING_PAYMENT_ADDRESS)) == 0);
auto paymentaddr2 = DecodePaymentAddress(addr_string);
BOOST_CHECK(IsValidPaymentAddress(paymentaddr2));
BOOST_ASSERT(boost::get<SaplingPaymentAddress>(&paymentaddr2) != nullptr);
auto addr2 = boost::get<SaplingPaymentAddress>(paymentaddr2);
BOOST_CHECK(addr == addr2);
}
}
}
BOOST_AUTO_TEST_SUITE_END()