mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-15 12:51:00 +02:00
Add asset and value blinding functionality
This commit is contained in:
parent
8b8256d9fa
commit
f81122f948
6 changed files with 432 additions and 8 deletions
|
|
@ -97,6 +97,7 @@ BITCOIN_CORE_H = \
|
|||
base58.h \
|
||||
bech32.h \
|
||||
blech32.h \
|
||||
blind.h \
|
||||
bloom.h \
|
||||
blockencodings.h \
|
||||
blockfilter.h \
|
||||
|
|
@ -114,6 +115,7 @@ BITCOIN_CORE_H = \
|
|||
compat/endian.h \
|
||||
compat/sanity.h \
|
||||
compressor.h \
|
||||
confidential_validation.h \
|
||||
consensus/consensus.h \
|
||||
consensus/tx_verify.h \
|
||||
core_io.h \
|
||||
|
|
@ -233,6 +235,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
block_proof.cpp \
|
||||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
confidential_validation.cpp \
|
||||
consensus/tx_verify.cpp \
|
||||
httprpc.cpp \
|
||||
httpserver.cpp \
|
||||
|
|
@ -412,6 +415,7 @@ libbitcoin_common_a_SOURCES = \
|
|||
base58.cpp \
|
||||
bech32.cpp \
|
||||
blech32.cpp \
|
||||
blind.cpp \
|
||||
chainparams.cpp \
|
||||
coins.cpp \
|
||||
compressor.cpp \
|
||||
|
|
|
|||
190
src/blind.cpp
Normal file
190
src/blind.cpp
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
// Copyright (c) 2017-2019 The Elements Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <blind.h>
|
||||
|
||||
#include <hash.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <primitives/confidential.h>
|
||||
#include <issuance.h>
|
||||
#include <random.h>
|
||||
#include <util.h>
|
||||
|
||||
static secp256k1_context* secp256k1_blind_context = NULL;
|
||||
|
||||
class Blind_ECC_Init {
|
||||
public:
|
||||
Blind_ECC_Init() {
|
||||
assert(secp256k1_blind_context == NULL);
|
||||
|
||||
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||
assert(ctx != NULL);
|
||||
|
||||
secp256k1_blind_context = ctx;
|
||||
}
|
||||
|
||||
~Blind_ECC_Init() {
|
||||
secp256k1_context *ctx = secp256k1_blind_context;
|
||||
secp256k1_blind_context = NULL;
|
||||
|
||||
if (ctx) {
|
||||
secp256k1_context_destroy(ctx);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static Blind_ECC_Init ecc_init_on_load;
|
||||
|
||||
bool UnblindConfidentialPair(const CKey& blinding_key, const CConfidentialValue& conf_value, const CConfidentialAsset& conf_asset, const CConfidentialNonce& nonce_commitment, const CScript& committedScript, const std::vector<unsigned char>& vchRangeproof, CAmount& amount_out, uint256& blinding_factor_out, CAsset& asset_out, uint256& asset_blinding_factor_out)
|
||||
{
|
||||
if (!blinding_key.IsValid() || vchRangeproof.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
CPubKey ephemeral_key(nonce_commitment.vchCommitment);
|
||||
if (nonce_commitment.vchCommitment.size() > 0 && !ephemeral_key.IsFullyValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ECDH or not depending on if nonce commitment is non-empty
|
||||
uint256 nonce;
|
||||
bool blank_nonce = false;
|
||||
if (nonce_commitment.vchCommitment.size() > 0) {
|
||||
nonce = blinding_key.ECDH(ephemeral_key);
|
||||
CSHA256().Write(nonce.begin(), 32).Finalize(nonce.begin());
|
||||
} else {
|
||||
// Use blinding key directly, and don't commit to a scriptpubkey
|
||||
// This is used for issuance inputs.
|
||||
blank_nonce = true;
|
||||
nonce = uint256(std::vector<unsigned char>(blinding_key.begin(), blinding_key.end()));
|
||||
}
|
||||
|
||||
// API-prescribed sidechannel maximum size, though we only use 64 bytes
|
||||
unsigned char msg[4096] = {0};
|
||||
// 32 bytes of asset type, 32 bytes of asset blinding factor in sidechannel
|
||||
size_t msg_size = 64;
|
||||
|
||||
// If value is unblinded, we don't support unblinding just the asset
|
||||
if (!conf_value.IsCommitment()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Valid asset commitment?
|
||||
secp256k1_generator observed_gen;
|
||||
if (conf_asset.IsCommitment()) {
|
||||
if (secp256k1_generator_parse(secp256k1_blind_context, &observed_gen, &conf_asset.vchCommitment[0]) != 1)
|
||||
return false;
|
||||
} else if (conf_asset.IsExplicit()) {
|
||||
if (secp256k1_generator_generate(secp256k1_blind_context, &observed_gen, conf_asset.GetAsset().begin()) != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Valid value commitment?
|
||||
secp256k1_pedersen_commitment value_commit;
|
||||
if (secp256k1_pedersen_commitment_parse(secp256k1_blind_context, &value_commit, conf_value.vchCommitment.data()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rewind rangeproof
|
||||
uint64_t min_value, max_value, amount;
|
||||
if (!secp256k1_rangeproof_rewind(secp256k1_blind_context, blinding_factor_out.begin(), &amount, msg, &msg_size, nonce.begin(), &min_value, &max_value, &value_commit, &vchRangeproof[0], vchRangeproof.size(), (committedScript.size() && !blank_nonce)? &committedScript.front(): NULL, blank_nonce ? 0 : committedScript.size(), &observed_gen)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Value sidechannel must be a transaction-valid amount (should be belt-and-suspenders check)
|
||||
if (amount > (uint64_t)MAX_MONEY || !MoneyRange((CAmount)amount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convienience pointers to starting point of each recovered 32 byte message
|
||||
unsigned char *asset_type = msg;
|
||||
unsigned char *asset_blinder = msg+32;
|
||||
|
||||
// Asset sidechannel of asset type + asset blinder
|
||||
secp256k1_generator recalculated_gen;
|
||||
if (msg_size != 64 || secp256k1_generator_generate_blinded(secp256k1_blind_context, &recalculated_gen, asset_type, asset_blinder) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Serialize both generators then compare
|
||||
unsigned char observed_generator[33];
|
||||
unsigned char derived_generator[33];
|
||||
secp256k1_generator_serialize(secp256k1_blind_context, observed_generator, &observed_gen);
|
||||
secp256k1_generator_serialize(secp256k1_blind_context, derived_generator, &recalculated_gen);
|
||||
if (memcmp(observed_generator, derived_generator, sizeof(observed_generator))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
amount_out = (CAmount)amount;
|
||||
asset_out = CAsset(std::vector<unsigned char>(asset_type, asset_type+32));
|
||||
asset_blinding_factor_out = uint256(std::vector<unsigned char>(asset_blinder, asset_blinder+32));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create surjection proof
|
||||
bool SurjectOutput(CTxOutWitness& txoutwit, const std::vector<secp256k1_fixed_asset_tag>& surjection_targets, const std::vector<secp256k1_generator>& target_asset_generators, const std::vector<uint256 >& target_asset_blinders, const std::vector<const unsigned char*> asset_blindptrs, const secp256k1_generator& output_asset_gen, const CAsset& asset)
|
||||
{
|
||||
int ret;
|
||||
// 1 to 3 targets
|
||||
size_t nInputsToSelect = std::min((size_t)3, surjection_targets.size());
|
||||
unsigned char randseed[32];
|
||||
GetStrongRandBytes(randseed, 32);
|
||||
size_t input_index;
|
||||
secp256k1_surjectionproof proof;
|
||||
secp256k1_fixed_asset_tag tag;
|
||||
memcpy(&tag, asset.begin(), 32);
|
||||
// Find correlation between asset tag and listed input tags
|
||||
if (secp256k1_surjectionproof_initialize(secp256k1_blind_context, &proof, &input_index, &surjection_targets[0], surjection_targets.size(), nInputsToSelect, &tag, 100, randseed) == 0) {
|
||||
return false;
|
||||
}
|
||||
// Using the input chosen, build proof
|
||||
ret = secp256k1_surjectionproof_generate(secp256k1_blind_context, &proof, target_asset_generators.data(), target_asset_generators.size(), &output_asset_gen, input_index, target_asset_blinders[input_index].begin(), asset_blindptrs[asset_blindptrs.size()-1]);
|
||||
assert(ret == 1);
|
||||
// Double-check answer
|
||||
ret = secp256k1_surjectionproof_verify(secp256k1_blind_context, &proof, target_asset_generators.data(), target_asset_generators.size(), &output_asset_gen);
|
||||
assert(ret != 0);
|
||||
|
||||
// Serialize into output witness structure
|
||||
size_t output_len = secp256k1_surjectionproof_serialized_size(secp256k1_blind_context, &proof);
|
||||
txoutwit.vchSurjectionproof.resize(output_len);
|
||||
secp256k1_surjectionproof_serialize(secp256k1_blind_context, &txoutwit.vchSurjectionproof[0], &output_len, &proof);
|
||||
assert(output_len == txoutwit.vchSurjectionproof.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GenerateRangeproof(std::vector<unsigned char>& rangeproof, const std::vector<unsigned char*>& value_blindptrs, const uint256& nonce, const CAmount amount, const CScript& scriptPubKey, const secp256k1_pedersen_commitment& value_commit, const secp256k1_generator& gen, const CAsset& asset, std::vector<const unsigned char*>& asset_blindptrs)
|
||||
{
|
||||
// Prep range proof
|
||||
size_t nRangeProofLen = 5134;
|
||||
rangeproof.resize(nRangeProofLen);
|
||||
|
||||
// Compose sidechannel message to convey asset info (ID and asset blinds)
|
||||
unsigned char asset_message[64];
|
||||
memcpy(asset_message, asset.begin(), 32);
|
||||
memcpy(asset_message+32, asset_blindptrs[asset_blindptrs.size()-1], 32);
|
||||
|
||||
// Sign rangeproof
|
||||
// If min_value is 0, scriptPubKey must be unspendable
|
||||
int res = secp256k1_rangeproof_sign(secp256k1_blind_context, rangeproof.data(), &nRangeProofLen, scriptPubKey.IsUnspendable() ? 0 : 1, &value_commit, value_blindptrs.back(), nonce.begin(), std::min(std::max((int)gArgs.GetArg("-ct_exponent", 0), -1),18), std::min(std::max((int)gArgs.GetArg("-ct_bits", 36), 1), 51), amount, asset_message, sizeof(asset_message), scriptPubKey.size() ? &scriptPubKey.front() : NULL, scriptPubKey.size(), &gen);
|
||||
rangeproof.resize(nRangeProofLen);
|
||||
return (res == 1);
|
||||
}
|
||||
|
||||
void BlindAsset(CConfidentialAsset& conf_asset, secp256k1_generator& asset_gen, const CAsset& asset, const unsigned char* asset_blindptr)
|
||||
{
|
||||
conf_asset.vchCommitment.resize(CConfidentialAsset::nCommittedSize);
|
||||
int ret = secp256k1_generator_generate_blinded(secp256k1_blind_context, &asset_gen, asset.begin(), asset_blindptr);
|
||||
assert(ret == 1);
|
||||
ret = secp256k1_generator_serialize(secp256k1_blind_context, conf_asset.vchCommitment.data(), &asset_gen);
|
||||
assert(ret != 0);
|
||||
}
|
||||
|
||||
void CreateValueCommitment(CConfidentialValue& conf_value, secp256k1_pedersen_commitment& value_commit, const unsigned char* value_blindptr, const secp256k1_generator& asset_gen, const CAmount amount)
|
||||
{
|
||||
int ret;
|
||||
conf_value.vchCommitment.resize(CConfidentialValue::nCommittedSize);
|
||||
ret = secp256k1_pedersen_commit(secp256k1_blind_context, &value_commit, value_blindptr, amount, &asset_gen);
|
||||
assert(ret != 0);
|
||||
secp256k1_pedersen_commitment_serialize(secp256k1_blind_context, conf_value.vchCommitment.data(), &value_commit);
|
||||
assert(conf_value.IsValid());
|
||||
}
|
||||
38
src/blind.h
Normal file
38
src/blind.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2017-2019 The Elements Core developers
|
||||
// // Distributed under the MIT software license, see the accompanying
|
||||
// // file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_WALLET_BLIND_H
|
||||
#define BITCOIN_WALLET_BLIND_H
|
||||
|
||||
#include <key.h>
|
||||
#include <pubkey.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <primitives/confidential.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_rangeproof.h>
|
||||
#include <secp256k1_surjectionproof.h>
|
||||
|
||||
//! ELEMENTS: 36-bit rangeproof size
|
||||
static const size_t DEFAULT_RANGEPROOF_SIZE = 2893;
|
||||
|
||||
/*
|
||||
* Unblind a pair of confidental asset and value.
|
||||
* Note that unblinded data will only be outputted if *BOTH* asset and value could be unblinded.
|
||||
*
|
||||
* blinding_key is used to create the nonce to rewind the rangeproof in conjunction with the nNonce commitment. In the case of a 0-length nNonce, the blinding key is directly used as the nonce.
|
||||
* Currently there is only a sidechannel message in the rangeproof so a valid rangeproof must
|
||||
* be included in the pair to recover value and asset data.
|
||||
*/
|
||||
bool UnblindConfidentialPair(const CKey& blinding_key, const CConfidentialValue& conf_value, const CConfidentialAsset& conf_asset, const CConfidentialNonce& nonce_commitment, const CScript& committedScript, const std::vector<unsigned char>& vchRangeproof, CAmount& amount_out, uint256& blinding_factor_out, CAsset& asset_out, uint256& asset_blinding_factor_out);
|
||||
|
||||
bool GenerateRangeproof(std::vector<unsigned char>& rangeproof, const std::vector<unsigned char*>& value_blindptrs, const uint256& nonce, const CAmount amount, const CScript& scriptPubKey, const secp256k1_pedersen_commitment& value_commit, const secp256k1_generator& gen, const CAsset& asset, std::vector<const unsigned char*>& asset_blindptrs);
|
||||
|
||||
bool SurjectOutput(CTxOutWitness& txoutwit, const std::vector<secp256k1_fixed_asset_tag>& surjection_targets, const std::vector<secp256k1_generator>& target_asset_generators, const std::vector<uint256 >& target_asset_blinders, const std::vector<const unsigned char*> asset_blindptrs, const secp256k1_generator& output_asset_gen, const CAsset& asset);
|
||||
|
||||
void BlindAsset(CConfidentialAsset& conf_asset, secp256k1_generator& asset_gen, const CAsset& asset, const unsigned char* asset_blindptr);
|
||||
|
||||
void CreateValueCommitment(CConfidentialValue& conf_value, secp256k1_pedersen_commitment& value_commit, const unsigned char* value_blindptr, const secp256k1_generator& asset_gen, const CAmount amount);
|
||||
|
||||
#endif //BITCOIN_WALLET_BLIND_H
|
||||
107
src/confidential_validation.cpp
Normal file
107
src/confidential_validation.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
#include <confidential_validation.h>
|
||||
#include <issuance.h>
|
||||
#include <pegins.h>
|
||||
#include <script/sigcache.h>
|
||||
#include <blind.h>
|
||||
|
||||
namespace {
|
||||
static secp256k1_context *secp256k1_ctx_verify_amounts;
|
||||
|
||||
class CSecp256k1Init {
|
||||
public:
|
||||
CSecp256k1Init() {
|
||||
assert(secp256k1_ctx_verify_amounts == NULL);
|
||||
secp256k1_ctx_verify_amounts = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
||||
assert(secp256k1_ctx_verify_amounts != NULL);
|
||||
}
|
||||
~CSecp256k1Init() {
|
||||
assert(secp256k1_ctx_verify_amounts != NULL);
|
||||
secp256k1_context_destroy(secp256k1_ctx_verify_amounts);
|
||||
secp256k1_ctx_verify_amounts = NULL;
|
||||
}
|
||||
};
|
||||
static CSecp256k1Init instance_of_csecp256k1;
|
||||
}
|
||||
|
||||
bool CRangeCheck::operator()() {
|
||||
if (val->IsExplicit()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CachingRangeProofChecker(store).VerifyRangeProof(rangeproof, val->vchCommitment, assetCommitment, scriptPubKey, secp256k1_ctx_verify_amounts)) {
|
||||
error = SCRIPT_ERR_RANGEPROOF;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CBalanceCheck::operator()() {
|
||||
if (!secp256k1_pedersen_verify_tally(secp256k1_ctx_verify_amounts, vpCommitsIn.data(), vpCommitsIn.size(), vpCommitsOut.data(), vpCommitsOut.size())) {
|
||||
error = SCRIPT_ERR_PEDERSEN_TALLY;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSurjectionCheck::operator()() {
|
||||
return CachingSurjectionProofChecker(store).VerifySurjectionProof(proof, vTags, gen, secp256k1_ctx_verify_amounts, wtxid);
|
||||
}
|
||||
|
||||
// Destroys the check in the case of no queue, or passes its ownership to the queue.
|
||||
ScriptError QueueCheck(std::vector<CCheck*>* queue, CCheck* check) {
|
||||
if (queue != NULL) {
|
||||
queue->push_back(check);
|
||||
return SCRIPT_ERR_OK;
|
||||
}
|
||||
bool success = (*check)();
|
||||
ScriptError err = check->GetScriptError();
|
||||
delete check;
|
||||
return success ? SCRIPT_ERR_OK : err;
|
||||
}
|
||||
|
||||
// Helper function for VerifyAmount(), not exported
|
||||
static bool VerifyIssuanceAmount(secp256k1_pedersen_commitment& value_commit, secp256k1_generator& asset_gen,
|
||||
const CAsset& asset, const CConfidentialValue& value, const std::vector<unsigned char>& rangeproof,
|
||||
std::vector<CCheck*>* checks, const bool store_result)
|
||||
{
|
||||
// This is used to add in the explicit values
|
||||
unsigned char explicit_blinds[32];
|
||||
memset(explicit_blinds, 0, sizeof(explicit_blinds));
|
||||
int ret;
|
||||
|
||||
ret = secp256k1_generator_generate(secp256k1_ctx_verify_amounts, &asset_gen, asset.begin());
|
||||
assert(ret == 1);
|
||||
|
||||
// Build value commitment
|
||||
if (value.IsExplicit()) {
|
||||
if (!MoneyRange(value.GetAmount()) || value.GetAmount() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (!rangeproof.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ret = secp256k1_pedersen_commit(secp256k1_ctx_verify_amounts, &value_commit, explicit_blinds, value.GetAmount(), &asset_gen);
|
||||
// The explicit_blinds are all 0, and the amount is not 0. So secp256k1_pedersen_commit does not fail.
|
||||
assert(ret == 1);
|
||||
} else if (value.IsCommitment()) {
|
||||
// Verify range proof
|
||||
std::vector<unsigned char> vchAssetCommitment(CConfidentialAsset::nExplicitSize);
|
||||
secp256k1_generator_serialize(secp256k1_ctx_verify_amounts, vchAssetCommitment.data(), &asset_gen);
|
||||
if (QueueCheck(checks, new CRangeCheck(&value, rangeproof, vchAssetCommitment, CScript(), store_result)) != SCRIPT_ERR_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (secp256k1_pedersen_commitment_parse(secp256k1_ctx_verify_amounts, &value_commit, value.vchCommitment.data()) != 1) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
87
src/confidential_validation.h
Normal file
87
src/confidential_validation.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
#ifndef BITCOIN_CONFIDENTIAL_VALIDATION_H
|
||||
#define BITCOIN_CONFIDENTIAL_VALIDATION_H
|
||||
|
||||
#include <amount.h>
|
||||
#include <asset.h>
|
||||
#include <coins.h>
|
||||
#include <primitives/confidential.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script_error.h>
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_rangeproof.h>
|
||||
#include <secp256k1_surjectionproof.h>
|
||||
#include <uint256.h>
|
||||
|
||||
|
||||
/**
|
||||
* ELEMENTS:
|
||||
* Closure representing one verification, either script or range checks.
|
||||
* Note that this stores references to the spending transaction
|
||||
*/
|
||||
class CCheck
|
||||
{
|
||||
protected:
|
||||
ScriptError error;
|
||||
|
||||
public:
|
||||
CCheck() : error(SCRIPT_ERR_UNKNOWN_ERROR) {}
|
||||
virtual ~CCheck() {}
|
||||
|
||||
virtual bool operator()() = 0;
|
||||
|
||||
ScriptError GetScriptError() const { return error; }
|
||||
};
|
||||
|
||||
/** Closure representing one output range check. */
|
||||
class CRangeCheck : public CCheck
|
||||
{
|
||||
private:
|
||||
const CConfidentialValue* val;
|
||||
const std::vector<unsigned char>& rangeproof;
|
||||
// *Must* be a commitment, not an explicit value
|
||||
const std::vector<unsigned char> assetCommitment;
|
||||
const CScript scriptPubKey;
|
||||
const bool store;
|
||||
|
||||
public:
|
||||
CRangeCheck(const CConfidentialValue* val_, const std::vector<unsigned char>& rangeproof_, const std::vector<unsigned char>& assetCommitment_, const CScript& scriptPubKey_, const bool storeIn) : val(val_), rangeproof(rangeproof_), assetCommitment(assetCommitment_), scriptPubKey(scriptPubKey_), store(storeIn) {}
|
||||
|
||||
bool operator()();
|
||||
};
|
||||
|
||||
/** Closure representing a transaction amount balance check. */
|
||||
class CBalanceCheck : public CCheck
|
||||
{
|
||||
private:
|
||||
std::vector<secp256k1_pedersen_commitment> vData;
|
||||
std::vector<secp256k1_pedersen_commitment *> vpCommitsIn, vpCommitsOut;
|
||||
|
||||
public:
|
||||
CBalanceCheck(std::vector<secp256k1_pedersen_commitment>& vData_, std::vector<secp256k1_pedersen_commitment*>& vpCommitsIn_, std::vector<secp256k1_pedersen_commitment*>& vpCommitsOut_) {
|
||||
vData.swap(vData_);
|
||||
vpCommitsIn.swap(vpCommitsIn_);
|
||||
vpCommitsOut.swap(vpCommitsOut_);
|
||||
}
|
||||
|
||||
bool operator()();
|
||||
};
|
||||
|
||||
class CSurjectionCheck : public CCheck
|
||||
{
|
||||
private:
|
||||
secp256k1_surjectionproof proof;
|
||||
std::vector<secp256k1_generator> vTags;
|
||||
secp256k1_generator gen;
|
||||
uint256 wtxid;
|
||||
const bool store;
|
||||
public:
|
||||
CSurjectionCheck(secp256k1_surjectionproof& proof_in, std::vector<secp256k1_generator>& tags_in, secp256k1_generator& gen_in, uint256& wtxid_in, const bool store_in) : proof(proof_in), vTags(tags_in), gen(gen_in), wtxid(wtxid_in), store(store_in) {}
|
||||
|
||||
bool operator()();
|
||||
};
|
||||
|
||||
ScriptError QueueCheck(std::vector<CCheck*>* queue, CCheck* check);
|
||||
|
||||
|
||||
#endif // BITCOIN_CONFIDENTIAL_VALIDATION_H
|
||||
|
|
@ -5,16 +5,15 @@
|
|||
#ifndef BITCOIN_PRIMITIVES_TXWITNESS_H
|
||||
#define BITCOIN_PRIMITIVES_TXWITNESS_H
|
||||
|
||||
#include <primitives/confidential.h>
|
||||
#include <script/script.h>
|
||||
#include <uint256.h>
|
||||
|
||||
class CTxInWitness
|
||||
{
|
||||
public:
|
||||
// TODO generalize CScriptWitness into just CWitness
|
||||
//TODO(rebase) CA/CT
|
||||
//std::vector<unsigned char> vchIssuanceAmountRangeproof;
|
||||
//std::vector<unsigned char> vchInflationKeysRangeproof;
|
||||
std::vector<unsigned char> vchIssuanceAmountRangeproof;
|
||||
std::vector<unsigned char> vchInflationKeysRangeproof;
|
||||
CScriptWitness scriptWitness;
|
||||
// Re-use script witness struct to include its own witness
|
||||
CScriptWitness m_pegin_witness;
|
||||
|
|
@ -34,13 +33,12 @@ public:
|
|||
|
||||
bool IsNull() const
|
||||
{
|
||||
//return vchIssuanceAmountRangeproof.empty() && vchInflationKeysRangeproof.empty() && scriptWitness.IsNull() && m_pegin_witness.IsNull();
|
||||
return scriptWitness.IsNull() && m_pegin_witness.IsNull();
|
||||
return vchIssuanceAmountRangeproof.empty() && vchInflationKeysRangeproof.empty() && scriptWitness.IsNull() && m_pegin_witness.IsNull();
|
||||
}
|
||||
void SetNull()
|
||||
{
|
||||
//vchIssuanceAmountRangeproof.clear();
|
||||
//vchInflationKeysRangeproof.clear();
|
||||
vchIssuanceAmountRangeproof.clear();
|
||||
vchInflationKeysRangeproof.clear();
|
||||
scriptWitness.stack.clear();
|
||||
m_pegin_witness.stack.clear();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue