Skip to content

Commit

Permalink
Merge pull request #146 from navcoin/factor-out-blsct-wallet
Browse files Browse the repository at this point in the history
Factor out BLSCT wallet code
  • Loading branch information
aguycalled authored Mar 19, 2024
2 parents 08b1849 + 32aeb4d commit f9add5f
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 108 deletions.
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ BLSCT_H = \
blsct/signature.h \
blsct/wallet/address.h \
blsct/wallet/hdchain.h \
blsct/wallet/helpers.h \
blsct/wallet/keyman.h \
blsct/wallet/keyring.h \
blsct/wallet/txfactory.h \
Expand Down Expand Up @@ -509,6 +510,7 @@ libbitcoin_node_a_SOURCES = \
bip324.cpp \
blockencodings.cpp \
blockfilter.cpp \
blsct/wallet/verification.cpp \
chain.cpp \
chainparams.cpp \
consensus/tx_verify.cpp \
Expand Down Expand Up @@ -657,6 +659,7 @@ libbitcoin_wallet_a_SOURCES = \
blsct/set_mem_proof/set_mem_proof_setup.cpp \
blsct/signature.cpp \
blsct/wallet/address.cpp \
blsct/wallet/helpers.cpp \
blsct/wallet/keyman.cpp \
blsct/wallet/keyring.cpp \
blsct/wallet/txfactory.cpp \
Expand Down
84 changes: 84 additions & 0 deletions src/blsct/wallet/helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2024 The Navcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <blsct/eip_2333/bls12_381_keygen.h>
#include <blsct/wallet/helpers.h>

namespace blsct {
uint64_t CalculateViewTag(const MclG1Point& blindingKey, const MclScalar& viewKey)
{
HashWriter hash{};
hash << (blindingKey * viewKey);

return (hash.GetHash().GetUint64(0) & 0xFFFF);
}

CKeyID CalculateHashId(const MclG1Point& blindingKey, const MclG1Point& spendingKey, const MclScalar& viewKey)
{
auto t = blindingKey * viewKey;
auto dh = MclG1Point::GetBasePoint() * t.GetHashWithSalt(0).Negate();
auto D_prime = spendingKey + dh;

return blsct::PublicKey(D_prime).GetID();
}

MclScalar CalculatePrivateSpendingKey(const MclG1Point& blindingKey, const MclScalar& viewKey, const MclScalar& spendingKey, const int64_t& account, const uint64_t& address)
{
HashWriter string{};

string << std::vector<unsigned char>(subAddressHeader.begin(), subAddressHeader.end());
string << viewKey;
string << account;
string << address;

MclG1Point t = blindingKey * viewKey;

return t.GetHashWithSalt(0) + spendingKey + MclScalar(string.GetHash());
}

MclG1Point CalculateNonce(const MclG1Point& blindingKey, const MclScalar& viewKey)
{
return blindingKey * viewKey;
}

SubAddress DeriveSubAddress(const PrivateKey& viewKey, const PublicKey& spendKey, const SubAddressIdentifier& subAddressId)
{
return SubAddress(viewKey, spendKey, subAddressId);
}

MclScalar FromSeedToChildKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 130);
}

MclScalar FromChildToTransactionKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 0);
}

MclScalar FromChildToBlindingKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 1);
}

MclScalar FromChildToTokenKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 2);
}

MclScalar FromTransactionToViewKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 0);
}

MclScalar FromTransactionToSpendKey(const MclScalar& seed)
{
return BLS12_381_KeyGen::derive_child_SK(seed, 1);
}

MclScalar GenRandomSeed()
{
return BLS12_381_KeyGen::derive_master_SK(MclScalar::Rand(true).GetVch());
}
} // namespace blsct
29 changes: 29 additions & 0 deletions src/blsct/wallet/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2023 The Navcoin developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef NAVCOIN_BLSCT_WALLET_HELPERS_H
#define NAVCOIN_BLSCT_WALLET_HELPERS_H

#include <blsct/arith/mcl/mcl.h>
#include <blsct/public_key.h>
#include <blsct/wallet/address.h>
#include <hash.h>
#include <pubkey.h>

namespace blsct {
uint64_t CalculateViewTag(const MclG1Point& blindingKey, const MclScalar& viewKey);
CKeyID CalculateHashId(const MclG1Point& blindingKey, const MclG1Point& spendingKey, const MclScalar& viewKey);
MclScalar CalculatePrivateSpendingKey(const MclG1Point& blindingKey, const MclScalar& viewKey, const MclScalar& spendingKey, const int64_t& account, const uint64_t& address);
MclG1Point CalculateNonce(const MclG1Point& blindingKey, const MclScalar& viewKey);
SubAddress DeriveSubAddress(const PrivateKey& viewKey, const PublicKey& spendKey, const SubAddressIdentifier& subAddressId);
MclScalar FromSeedToChildKey(const MclScalar& seed);
MclScalar FromChildToTransactionKey(const MclScalar& seed);
MclScalar FromChildToBlindingKey(const MclScalar& seed);
MclScalar FromChildToTokenKey(const MclScalar& seed);
MclScalar FromTransactionToViewKey(const MclScalar& seed);
MclScalar FromTransactionToSpendKey(const MclScalar& seed);
MclScalar GenRandomSeed();
} // namespace blsct

#endif // NAVCOIN_BLSCT_WALLET_HELPERS_H
56 changes: 20 additions & 36 deletions src/blsct/wallet/keyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@ bool KeyMan::AddCryptedKey(const PublicKey& vchPubKey,

PrivateKey KeyMan::GenerateNewSeed()
{
PrivateKey key(BLS12_381_KeyGen::derive_master_SK(MclScalar::Rand(true).GetVch()));
return key;
return GenRandomSeed();
}

void KeyMan::LoadHDChain(const blsct::HDChain& chain)
Expand Down Expand Up @@ -195,13 +194,12 @@ void KeyMan::SetHDSeed(const PrivateKey& key)
blsct::HDChain newHdChain;

auto seed = key.GetPublicKey();
auto scalarMasterKey = key.GetScalar();
auto childKey = BLS12_381_KeyGen::derive_child_SK(scalarMasterKey, 130);
auto transactionKey = BLS12_381_KeyGen::derive_child_SK(childKey, 0);
auto blindingKey = PrivateKey(BLS12_381_KeyGen::derive_child_SK(childKey, 1));
auto tokenKey = PrivateKey(BLS12_381_KeyGen::derive_child_SK(childKey, 2));
auto viewKey = PrivateKey(BLS12_381_KeyGen::derive_child_SK(transactionKey, 0));
auto spendKey = PrivateKey(BLS12_381_KeyGen::derive_child_SK(transactionKey, 1));
auto childKey = FromSeedToChildKey(key.GetScalar());
auto transactionKey = FromChildToTransactionKey(childKey);
auto blindingKey = PrivateKey(FromChildToBlindingKey(childKey));
auto tokenKey = PrivateKey(FromChildToTokenKey(childKey));
auto viewKey = PrivateKey(FromTransactionToViewKey(transactionKey));
auto spendKey = PrivateKey(FromTransactionToSpendKey(transactionKey));

newHdChain.nVersion = blsct::HDChain::VERSION_HD_BASE;
newHdChain.seed_id = key.GetPublicKey().GetID();
Expand Down Expand Up @@ -353,7 +351,7 @@ void KeyMan::UpdateTimeFirstKey(int64_t nCreateTime)

SubAddress KeyMan::GetSubAddress(const SubAddressIdentifier& id) const
{
return SubAddress(viewKey, spendPublicKey, id);
return DeriveSubAddress(viewKey, spendPublicKey, id);
};

bool KeyMan::HaveKey(const CKeyID& id) const
Expand Down Expand Up @@ -442,11 +440,7 @@ CKeyID KeyMan::GetHashId(const blsct::PublicKey& blindingKey, const blsct::Publi
if (!fViewKeyDefined || !viewKey.IsValid())
throw std::runtime_error(strprintf("%s: the wallet has no view key available", __func__));

auto t = blindingKey.GetG1Point() * viewKey.GetScalar();
auto dh = MclG1Point::GetBasePoint() * t.GetHashWithSalt(0).Negate();
auto D_prime = spendingKey.GetG1Point() + dh;

return PublicKey(D_prime).GetID();
return CalculateHashId(blindingKey.GetG1Point(), spendingKey.GetG1Point(), viewKey.GetScalar());
};

blsct::PrivateKey KeyMan::GetMasterSeedKey() const
Expand Down Expand Up @@ -503,32 +497,25 @@ blsct::PrivateKey KeyMan::GetSpendingKeyForOutput(const CTxOut& out, const SubAd

auto sk = GetSpendingKey();

HashWriter string{};

string << std::vector<unsigned char>(subAddressHeader.begin(), subAddressHeader.end());
string << viewKey;
string << id.account;
string << id.address;

MclG1Point t = out.blsctData.blindingKey * viewKey.GetScalar();
MclScalar ret = t.GetHashWithSalt(0) + sk.GetScalar() + MclScalar(string.GetHash());

return ret;
return CalculatePrivateSpendingKey(out.blsctData.blindingKey, viewKey.GetScalar(), sk.GetScalar(), id.account, id.address);
}

bulletproofs::AmountRecoveryResult<Mcl> KeyMan::RecoverOutputs(const std::vector<CTxOut>& outs)
using Arith = Mcl;

bulletproofs::AmountRecoveryResult<Arith> KeyMan::RecoverOutputs(const std::vector<CTxOut>& outs)
{
if (!fViewKeyDefined || !viewKey.IsValid())
return bulletproofs::AmountRecoveryResult<Mcl>::failure();
return bulletproofs::AmountRecoveryResult<Arith>::failure();

bulletproofs::RangeProofLogic<Mcl> rp;
std::vector<bulletproofs::AmountRecoveryRequest<Mcl>> reqs;
bulletproofs::RangeProofLogic<Arith> rp;
std::vector<bulletproofs::AmountRecoveryRequest<Arith>> reqs;
reqs.reserve(outs.size());

for (size_t i = 0; i < outs.size(); i++) {
CTxOut out = outs[i];
auto nonce = out.blsctData.blindingKey * viewKey.GetScalar();
reqs.push_back(bulletproofs::AmountRecoveryRequest<Mcl>::of(out.blsctData.rangeProof, nonce));
auto nonce = CalculateNonce(out.blsctData.blindingKey, viewKey.GetScalar());
bulletproofs::RangeProof<Arith> proof = out.blsctData.rangeProof;
reqs.push_back(bulletproofs::AmountRecoveryRequest<Arith>::of(proof, nonce));
}

return rp.RecoverAmounts(reqs);
Expand All @@ -539,10 +526,7 @@ bool KeyMan::IsMine(const blsct::PublicKey& blindingKey, const blsct::PublicKey&
if (!fViewKeyDefined || !viewKey.IsValid())
return false;

HashWriter hash{};
hash << (blindingKey.GetG1Point() * viewKey.GetScalar());

if (viewTag != (hash.GetHash().GetUint64(0) & 0xFFFF)) return false;
if (viewTag != CalculateViewTag(blindingKey.GetG1Point(), viewKey.GetScalar())) return false;

auto hashId = GetHashId(blindingKey, spendingKey);

Expand Down
3 changes: 1 addition & 2 deletions src/blsct/wallet/keyman.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
#ifndef NAVCOIN_BLSCT_KEYMAN_H
#define NAVCOIN_BLSCT_KEYMAN_H

#include <blsct/arith/mcl/mcl.h>
#include <blsct/double_public_key.h>
#include <blsct/eip_2333/bls12_381_keygen.h>
#include <blsct/private_key.h>
#include <blsct/public_key.h>
#include <blsct/range_proof/bulletproofs/amount_recovery_request.h>
#include <blsct/range_proof/bulletproofs/amount_recovery_result.h>
#include <blsct/range_proof/bulletproofs/range_proof_logic.h>
#include <blsct/wallet/address.h>
#include <blsct/wallet/hdchain.h>
#include <blsct/wallet/helpers.h>
#include <blsct/wallet/keyring.h>
#include <logging.h>
#include <wallet/crypter.h>
Expand Down
Loading

0 comments on commit f9add5f

Please sign in to comment.