Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lelantus improvements #1012

Merged
merged 30 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1f5444b
Formating fixed
levonpetrosyan93 Apr 6, 2021
9704df1
Lelantus fixes
levonpetrosyan93 Mar 4, 2021
0fec686
Fixing Range proof challenge generation
levonpetrosyan93 Mar 8, 2021
e9c67f4
Add new challenge generator with CHash256 and use it for new version
levonpetrosyan93 Mar 8, 2021
b4acff5
Linking transcripts betweed sigma and balance proofs, using unique_pt…
levonpetrosyan93 Mar 9, 2021
9f12c20
Use jsplit version instead of comparing height, add version into doma…
levonpetrosyan93 Mar 12, 2021
3a89a60
Minor fixes
levonpetrosyan93 Mar 15, 2021
9334771
Adding some comments
levonpetrosyan93 Mar 15, 2021
4185782
Removing unneeded functions from SigmaExtendedProver/Verifier
levonpetrosyan93 Mar 19, 2021
cabd9fa
Review comments applied
levonpetrosyan93 Mar 20, 2021
c459c8a
Adding schnorr proof for Qk
levonpetrosyan93 Mar 20, 2021
e5738b6
Added check to verify that n-th power is not returning 1
levonpetrosyan93 Mar 22, 2021
490da2f
Use template and merge 2 challenge generator classes
levonpetrosyan93 Mar 23, 2021
6df5e75
Review comment applied
levonpetrosyan93 Mar 23, 2021
fd60f7b
Version bump, testnet HF block, testnet blacklist
levonpetrosyan93 Mar 24, 2021
16aca29
Fixing a minor bug
levonpetrosyan93 Mar 29, 2021
8dcf785
Version 0.14.6.0
a-bezrukov Mar 29, 2021
81797b4
Index loading fixed
levonpetrosyan93 Mar 30, 2021
6dfaead
Saving set hash only if there are mints in the block
levonpetrosyan93 Mar 30, 2021
74716f6
Failing test fixed
levonpetrosyan93 Mar 30, 2021
49a1065
Fixing db reading error
levonpetrosyan93 Mar 30, 2021
be6e2dc
Changing HF block for mainnnet
levonpetrosyan93 Apr 2, 2021
580f842
Setting mainnet HF block
levonpetrosyan93 Apr 5, 2021
b2bfb13
Check unique-properties of ProUpRegTx when building new list
levonpetrosyan93 Apr 5, 2021
86cdb95
Added a comment in NthPower struct
levonpetrosyan93 Apr 7, 2021
532fe71
Moving catch to upper level
levonpetrosyan93 Apr 9, 2021
905dee5
Added catch at batch verification
levonpetrosyan93 Apr 9, 2021
c1a84ce
Adding vector sizes into transcript, inner product domain separator m…
levonpetrosyan93 Apr 13, 2021
148dca0
Moved HF block to April 22
levonpetrosyan93 Apr 13, 2021
0e6190e
Review comment applied
levonpetrosyan93 Apr 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 14)
define(_CLIENT_VERSION_REVISION, 5)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_REVISION, 6)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2021)
define(_COPYRIGHT_HOLDERS,[The %s developers])
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ liblelantus_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
liblelantus_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
liblelantus_a_SOURCES = \
liblelantus/challenge_generator.h \
liblelantus/challenge_generator.cpp \
liblelantus/challenge_generator_impl.h \
liblelantus/lelantus_primitives.h \
liblelantus/lelantus_primitives.cpp \
liblelantus/lelantus_proof.h \
Expand Down
111 changes: 66 additions & 45 deletions src/batchproof_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ void BatchProofContainer::init() {
}

void BatchProofContainer::finalize() {
if(fCollectProofs) {
for(const auto& itr : tempSigmaProofs) {
if (fCollectProofs) {
for (const auto& itr : tempSigmaProofs) {
sigmaProofs[itr.first].insert(sigmaProofs[itr.first].begin(), itr.second.begin(), itr.second.end());
}

for(const auto& itr : tempLelantusSigmaProofs) {
for (const auto& itr : tempLelantusSigmaProofs) {
lelantusSigmaProofs[itr.first].insert(lelantusSigmaProofs[itr.first].begin(), itr.second.begin(), itr.second.end());
}
} else {
Expand All @@ -48,28 +48,30 @@ void BatchProofContainer::add(sigma::CoinSpend* spend,

void BatchProofContainer::add(lelantus::JoinSplit* joinSplit,
const std::map<uint32_t, size_t>& setSizes,
const Scalar& challenge) {
const Scalar& challenge,
bool fStartLelantusBlacklist) {
const std::vector<lelantus::SigmaExtendedProof>& sigma_proofs = joinSplit->getLelantusProof().sigma_proofs;
const std::vector<Scalar>& serials = joinSplit->getCoinSerialNumbers();
const std::vector<uint32_t>& groupIds = joinSplit->getCoinGroupIds();

for(size_t i = 0; i < sigma_proofs.size(); i++) {
for (size_t i = 0; i < sigma_proofs.size(); i++) {
int coinGroupId = groupIds[i] % (CENT / 1000);
int64_t intDenom = (groupIds[i] - coinGroupId);
intDenom *= 1000;

sigma::CoinDenomination denomination;
bool isSigma = sigma::IntegerToDenomination(intDenom, denomination) && joinSplit->getVersion() == SIGMA_TO_LELANTUS_JOINSPLIT;
std::pair<uint32_t, bool> idAndFlag = std::make_pair(groupIds[i], isSigma);
bool isSigma = sigma::IntegerToDenomination(intDenom, denomination) && joinSplit->isSigmaToLelantus();
// pair(pair(set id, fAfterFixes), isSigmaToLelantus)
std::pair<std::pair<uint32_t, bool>, bool> idAndFlag = std::make_pair(std::make_pair(groupIds[i], fStartLelantusBlacklist), isSigma);
tempLelantusSigmaProofs[idAndFlag].push_back(LelantusSigmaProofData(sigma_proofs[i], serials[i], challenge, setSizes.at(groupIds[i])));
}
}

void BatchProofContainer::removeSigma(const sigma::spend_info_container& spendSerials) {
for(auto& spendSerial : spendSerials) {
for (auto& spendSerial : spendSerials) {
bool foundAtSigma = false;
for(auto& itr :sigmaProofs) {
if(itr.first.first == spendSerial.second.denomination && itr.first.second.first == spendSerial.second.coinGroupId) {
for (auto& itr :sigmaProofs) {
if (itr.first.first == spendSerial.second.denomination && itr.first.second.first == spendSerial.second.coinGroupId) {
auto& vProofs = itr.second;
for (auto dataItr = vProofs.begin(); dataItr != vProofs.end(); dataItr++) {
if (dataItr->coinSerialNumber == spendSerial.first) {
Expand All @@ -80,40 +82,53 @@ void BatchProofContainer::removeSigma(const sigma::spend_info_container& spendSe
}
}
}
if(!foundAtSigma) {
if (!foundAtSigma) {
int64_t denom;
sigma::DenominationToInteger(spendSerial.second.denomination, denom);
int id = denom / 1000 + spendSerial.second.coinGroupId;
std::pair<uint32_t, bool> key = std::make_pair(id, true);
if (lelantusSigmaProofs.count(key) > 0) {
auto &vProofs = lelantusSigmaProofs[key];
for (auto dataItr = vProofs.begin(); dataItr != vProofs.end(); dataItr++) {
if (dataItr->serialNumber == spendSerial.first) {
vProofs.erase(dataItr);
break;
}
// afterFixes bool with the pair of set id is considered separate set identifiers, so try to find in one set, if not found try also in another
std::pair<std::pair<uint32_t, bool>, bool> key1 = std::make_pair(std::make_pair(id, false), true);
std::pair<std::pair<uint32_t, bool>, bool> key2 = std::make_pair(std::make_pair(id, true), true);
std::vector<LelantusSigmaProofData>* vProofs;
if (lelantusSigmaProofs.count(key1) > 0)
vProofs = &lelantusSigmaProofs[key1];
else if (lelantusSigmaProofs.count(key2) > 0)
vProofs = &lelantusSigmaProofs[key2];
else
continue;
for (auto dataItr = vProofs->begin(); dataItr != vProofs->end(); dataItr++) {
if (dataItr->serialNumber == spendSerial.first) {
vProofs->erase(dataItr);
break;
}
}
}
}
}
void BatchProofContainer::removeLelantus(std::unordered_map<Scalar, int> spentSerials) {
for(auto& spendSerial : spentSerials) {
std::pair<uint32_t, bool> key = std::make_pair(spendSerial.second, false);
if (lelantusSigmaProofs.count(key) > 0) {
auto &vProofs = lelantusSigmaProofs[key];
for (auto dataItr = vProofs.begin(); dataItr != vProofs.end(); dataItr++) {
if (dataItr->serialNumber == spendSerial.first) {
vProofs.erase(dataItr);
break;
}
for (auto& spendSerial : spentSerials) {
// afterFixes bool with the pair of set id is considered separate set identifiers, so try to find in one set, if not found try also in another
std::pair<std::pair<uint32_t, bool>, bool> key1 = std::make_pair(std::make_pair(spendSerial.second, false), true);
std::pair<std::pair<uint32_t, bool>, bool> key2 = std::make_pair(std::make_pair(spendSerial.second, true), true);
std::vector<LelantusSigmaProofData>* vProofs;
if (lelantusSigmaProofs.count(key1) > 0)
vProofs = &lelantusSigmaProofs[key1];
else if (lelantusSigmaProofs.count(key2) > 0)
vProofs = &lelantusSigmaProofs[key2];
else
continue;

for (auto dataItr = vProofs->begin(); dataItr != vProofs->end(); dataItr++) {
if (dataItr->serialNumber == spendSerial.first) {
vProofs->erase(dataItr);
break;
}
}
}
}

void BatchProofContainer::batch_sigma() {
for(const auto& itr : sigmaProofs) {
for (const auto& itr : sigmaProofs) {
std::vector<GroupElement> anonymity_set;
sigma::CSigmaState* sigmaState = sigma::CSigmaState::GetState();
sigmaState->GetAnonymitySet(
Expand All @@ -132,7 +147,7 @@ void BatchProofContainer::batch_sigma() {
vector<sigma::SigmaPlusProof<Scalar, GroupElement>> proofs;
proofs.reserve(m);

for(auto& proofData : itr.second) {
for (auto& proofData : itr.second) {
serials.emplace_back(proofData.coinSerialNumber);
fPadding.emplace_back(proofData.fPadding);
setSizes.emplace_back(proofData.anonymitySetSize);
Expand All @@ -142,7 +157,7 @@ void BatchProofContainer::batch_sigma() {
auto params = sigma::Params::get_default();
sigma::SigmaPlusVerifier<Scalar, GroupElement> sigmaVerifier(params->get_g(), params->get_h(), params->get_n(), params->get_m());

if(!sigmaVerifier.batch_verify(anonymity_set, serials, fPadding, setSizes, proofs)) {
if (!sigmaVerifier.batch_verify(anonymity_set, serials, fPadding, setSizes, proofs)) {
LogPrintf("Sigma batch verification failed.");
throw std::invalid_argument("Sigma batch verification failed, please run Firo with -reindex -batching=0");
}
Expand All @@ -153,24 +168,21 @@ void BatchProofContainer::batch_sigma() {
void BatchProofContainer::batch_lelantus() {
auto params = lelantus::Params::get_default();

for(const auto& itr : lelantusSigmaProofs) {
for (const auto& itr : lelantusSigmaProofs) {
std::vector<GroupElement> anonymity_set;
if(!itr.first.second) {
if (!itr.first.second) {
lelantus::CLelantusState* state = lelantus::CLelantusState::GetState();
std::vector<lelantus::PublicCoin> coins;
uint256 blockHash;
state->GetCoinSetForSpend(
&chainActive,
chainActive.Height() - (ZC_MINT_CONFIRMATIONS - 1), // required 2 confirmation for mint to spend
itr.first.first,
blockHash,
state->GetAnonymitySet(
itr.first.first.first,
itr.first.first.second,
coins);
anonymity_set.reserve(coins.size());
for(auto& coin : coins)
for (auto& coin : coins)
anonymity_set.emplace_back(coin.getValue());
} else {
int coinGroupId = itr.first.first % (CENT / 1000);
int64_t intDenom = (itr.first.first - coinGroupId);
int coinGroupId = itr.first.first.first % (CENT / 1000);
int64_t intDenom = (itr.first.first.first - coinGroupId);
intDenom *= 1000;
sigma::CoinDenomination denomination;
sigma::IntegerToDenomination(intDenom, denomination);
Expand All @@ -184,7 +196,7 @@ void BatchProofContainer::batch_lelantus() {
coins);

anonymity_set.reserve(coins.size());
for(auto& coin : coins)
for (auto& coin : coins)
anonymity_set.emplace_back(coin + params->get_h1() * intDenom);
}

Expand All @@ -198,7 +210,7 @@ void BatchProofContainer::batch_lelantus() {
std::vector<Scalar> challenges;
challenges.reserve(m);

for(auto& proofData : itr.second) {
for (auto& proofData : itr.second) {
serials.emplace_back(proofData.serialNumber);
setSizes.emplace_back(proofData.anonymitySetSize);
proofs.emplace_back(proofData.lelantusSigmaProof);
Expand All @@ -208,7 +220,16 @@ void BatchProofContainer::batch_lelantus() {
lelantus::SigmaExtendedVerifier sigmaVerifier(params->get_g(), params->get_sigma_h(), params->get_sigma_n(),
params->get_sigma_m());

if(!sigmaVerifier.batchverify(anonymity_set, challenges, serials, setSizes, proofs)) {
bool isFail = false;
try {
if (!sigmaVerifier.batchverify(anonymity_set, challenges, serials, setSizes, proofs)) {
isFail = true;
}
} catch (std::invalid_argument&) {
isFail = true;
}

if (isFail) {
LogPrintf("Lelantus batch verification failed.");
throw std::invalid_argument("Lelantus batch verification failed, please run Firo with -reindex -batching=0");
}
Expand Down
11 changes: 6 additions & 5 deletions src/batchproof_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class BatchProofContainer {

void add(lelantus::JoinSplit* joinSplit,
const std::map<uint32_t, size_t>& setSizes,
const Scalar& challenge);
const Scalar& challenge,
bool fStartLelantusBlacklist);

void removeSigma(const sigma::spend_info_container& spendSerials);
void removeLelantus(std::unordered_map<Scalar, int> spentSerials);
Expand Down Expand Up @@ -70,15 +71,15 @@ class BatchProofContainer {

private:
static std::unique_ptr<BatchProofContainer> instance;
// map (denom, id) to (sigma proof, serial, set size)
// temp containers, to forget in case block connection fails
// map (denom, id) to (sigma proof, serial, set size)
std::map<std::pair<sigma::CoinDenomination, std::pair<int, bool>>, std::vector<SigmaProofData>> tempSigmaProofs;
// map (id, fIsSigmaToLelantus) to (sigma proof, serial, set size, challenge)
std::map<std::pair<uint32_t, bool>, std::vector<LelantusSigmaProofData>> tempLelantusSigmaProofs;
// map ((id, afterFixes), fIsSigmaToLelantus) to (sigma proof, serial, set size, challenge)
std::map<std::pair<std::pair<uint32_t, bool>, bool>, std::vector<LelantusSigmaProofData>> tempLelantusSigmaProofs;

// containers to keep proofs for batching
std::map<std::pair<sigma::CoinDenomination, std::pair<int, bool>>, std::vector<SigmaProofData>> sigmaProofs;
std::map<std::pair<uint32_t, bool>, std::vector<LelantusSigmaProofData>> lelantusSigmaProofs;
std::map<std::pair<std::pair<uint32_t, bool>, bool>, std::vector<LelantusSigmaProofData>> lelantusSigmaProofs;
};

#endif //FIRO_BATCHPROOF_CONTAINER_H
Loading