From f044cba41a28bc84f960d3e2a4b23ced4fbb6351 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Mon, 29 Feb 2016 13:44:46 -0500 Subject: [PATCH] Add base58 support for blinded addresses --- src/base58.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/base58.h | 5 +++++ src/chainparams.cpp | 3 +++ src/chainparams.h | 1 + 4 files changed, 54 insertions(+) diff --git a/src/base58.cpp b/src/base58.cpp index d1d60a6f1d..80890e6153 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -240,13 +240,49 @@ bool CBitcoinAddress::Set(const CTxDestination& dest) return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); } +CBitcoinAddress& CBitcoinAddress::AddBlindingKey(const CPubKey& pubkey) +{ + if (!pubkey.IsValid()) { + return *this; + } + assert(pubkey.size() == 33); + assert(!IsBlinded()); + std::vector data = vchVersion; + data.insert(data.end(), pubkey.begin(), pubkey.end()); + data.insert(data.end(), vchData.begin(), vchData.end()); + SetData(Params().Base58Prefix(CChainParams::BLINDED_ADDRESS), &data[0], data.size()); + return *this; +} + +CPubKey CBitcoinAddress::GetBlindingKey() const +{ + assert(IsBlinded()); + CPubKey pubkey(&vchData[1], &vchData[34]); + return pubkey; +} + +bool CBitcoinAddress::IsBlinded(const CChainParams& params) const +{ + return (vchVersion == params.Base58Prefix(CChainParams::BLINDED_ADDRESS) && vchData.size() > 34); +} + bool CBitcoinAddress::IsValid() const { return IsValid(Params()); } +CBitcoinAddress CBitcoinAddress::GetUnblinded() const +{ + CBitcoinAddress subaddr; + subaddr.SetData(std::vector(&vchData[0], &vchData[1]), &vchData[34], vchData.size() - 34); + return subaddr; +} + bool CBitcoinAddress::IsValid(const CChainParams& params) const { + if (IsBlinded(params)) { + return GetUnblinded().IsValid(params); + } bool fCorrectSize = vchData.size() == 20; bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) || vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS); @@ -255,6 +291,9 @@ bool CBitcoinAddress::IsValid(const CChainParams& params) const CTxDestination CBitcoinAddress::Get() const { + if (IsBlinded()) { + return GetUnblinded().Get(); + } if (!IsValid()) return CNoDestination(); uint160 id; @@ -269,6 +308,9 @@ CTxDestination CBitcoinAddress::Get() const bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const { + if (IsBlinded()) { + return GetUnblinded().GetKeyID(keyID); + } if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS)) return false; uint160 id; @@ -279,6 +321,9 @@ bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const bool CBitcoinAddress::IsScript() const { + if (IsBlinded()) { + return GetUnblinded().IsScript(); + } return IsValid() && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS); } diff --git a/src/base58.h b/src/base58.h index cccebc9e0e..23700a92d5 100644 --- a/src/base58.h +++ b/src/base58.h @@ -117,6 +117,11 @@ public: CTxDestination Get() const; bool GetKeyID(CKeyID &keyID) const; bool IsScript() const; + + CBitcoinAddress& AddBlindingKey(const CPubKey &pubkey); + CPubKey GetBlindingKey() const; + CBitcoinAddress GetUnblinded() const; + bool IsBlinded(const CChainParams& params = Params()) const; }; /** diff --git a/src/chainparams.cpp b/src/chainparams.cpp index bcabcc0dc9..1f23e2401a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -105,6 +105,7 @@ public: }; base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); + base58Prefixes[BLINDED_ADDRESS]= std::vector(1,26); base58Prefixes[SECRET_KEY] = std::vector(1,239); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); @@ -121,6 +122,7 @@ public: base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); + base58Prefixes[BLINDED_ADDRESS]= std::vector(1,11); base58Prefixes[SECRET_KEY] = std::vector(1,128); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container >(); @@ -186,6 +188,7 @@ public: }; base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); + base58Prefixes[BLINDED_ADDRESS]= std::vector(1,27); base58Prefixes[SECRET_KEY] = std::vector(1,239); base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container >(); base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container >(); diff --git a/src/chainparams.h b/src/chainparams.h index bc09bf04f6..479314a3c8 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -46,6 +46,7 @@ public: enum Base58Type { PUBKEY_ADDRESS, SCRIPT_ADDRESS, + BLINDED_ADDRESS, SECRET_KEY, EXT_PUBLIC_KEY, EXT_SECRET_KEY,