forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement and use secure BLS batch verification (#2681)
* Implement secure verification in bls_batchverifier * Rename CBLSInsecureBatchVerifier to CBLSBatchVerifier * Add unit tests for simple BLS verifcation and CBLSBatchVerifier
- Loading branch information
Showing
6 changed files
with
217 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
// Copyright (c) 2019 The Dash Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include "bls/bls.h" | ||
#include "bls/bls_batchverifier.h" | ||
#include "test/test_dash.h" | ||
|
||
#include <boost/test/unit_test.hpp> | ||
|
||
BOOST_FIXTURE_TEST_SUITE(bls_tests, BasicTestingSetup) | ||
|
||
BOOST_AUTO_TEST_CASE(bls_sig_tests) | ||
{ | ||
CBLSSecretKey sk1, sk2; | ||
sk1.MakeNewKey(); | ||
sk2.MakeNewKey(); | ||
|
||
uint256 msgHash1 = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); | ||
uint256 msgHash2 = uint256S("0000000000000000000000000000000000000000000000000000000000000002"); | ||
|
||
auto sig1 = sk1.Sign(msgHash1); | ||
auto sig2 = sk2.Sign(msgHash1); | ||
BOOST_CHECK(sig1.VerifyInsecure(sk1.GetPublicKey(), msgHash1)); | ||
BOOST_CHECK(!sig1.VerifyInsecure(sk1.GetPublicKey(), msgHash2)); | ||
BOOST_CHECK(!sig2.VerifyInsecure(sk1.GetPublicKey(), msgHash1)); | ||
BOOST_CHECK(!sig2.VerifyInsecure(sk2.GetPublicKey(), msgHash2)); | ||
BOOST_CHECK(sig2.VerifyInsecure(sk2.GetPublicKey(), msgHash1)); | ||
} | ||
|
||
struct Message | ||
{ | ||
uint32_t sourceId; | ||
uint32_t msgId; | ||
uint256 msgHash; | ||
CBLSSecretKey sk; | ||
CBLSPublicKey pk; | ||
CBLSSignature sig; | ||
bool valid; | ||
}; | ||
|
||
static void AddMessage(std::vector<Message>& vec, uint32_t sourceId, uint32_t msgId, uint32_t msgHash, bool valid) | ||
{ | ||
Message m; | ||
m.sourceId = sourceId; | ||
m.msgId = msgId; | ||
*((uint32_t*)m.msgHash.begin()) = msgHash; | ||
m.sk.MakeNewKey(); | ||
m.pk = m.sk.GetPublicKey(); | ||
m.sig = m.sk.Sign(m.msgHash); | ||
m.valid = valid; | ||
|
||
if (!valid) { | ||
CBLSSecretKey tmp; | ||
tmp.MakeNewKey(); | ||
m.sig = tmp.Sign(m.msgHash); | ||
} | ||
|
||
vec.emplace_back(m); | ||
} | ||
|
||
static void Verify(std::vector<Message>& vec, bool secureVerification, bool perMessageFallback) | ||
{ | ||
CBLSBatchVerifier<uint32_t, uint32_t> batchVerifier(secureVerification, perMessageFallback); | ||
|
||
std::set<uint32_t> expectedBadMessages; | ||
std::set<uint32_t> expectedBadSources; | ||
for (auto& m : vec) { | ||
if (!m.valid) { | ||
expectedBadMessages.emplace(m.msgId); | ||
expectedBadSources.emplace(m.sourceId); | ||
} | ||
|
||
batchVerifier.PushMessage(m.sourceId, m.msgId, m.msgHash, m.sig, m.pk); | ||
} | ||
|
||
batchVerifier.Verify(); | ||
|
||
BOOST_CHECK(batchVerifier.badSources == expectedBadSources); | ||
|
||
if (perMessageFallback) { | ||
BOOST_CHECK(batchVerifier.badMessages == expectedBadMessages); | ||
} else { | ||
BOOST_CHECK(batchVerifier.badMessages.empty()); | ||
} | ||
} | ||
|
||
static void Verify(std::vector<Message>& vec) | ||
{ | ||
Verify(vec, false, false); | ||
Verify(vec, true, false); | ||
Verify(vec, false, true); | ||
Verify(vec, true, true); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(batch_verifier_tests) | ||
{ | ||
std::vector<Message> msgs; | ||
|
||
// distinct messages from distinct sources | ||
AddMessage(msgs, 1, 1, 1, true); | ||
AddMessage(msgs, 2, 2, 2, true); | ||
AddMessage(msgs, 3, 3, 3, true); | ||
Verify(msgs); | ||
|
||
// distinct messages from same source | ||
AddMessage(msgs, 4, 4, 4, true); | ||
AddMessage(msgs, 4, 5, 5, true); | ||
AddMessage(msgs, 4, 6, 6, true); | ||
Verify(msgs); | ||
|
||
// invalid sig | ||
AddMessage(msgs, 7, 7, 7, false); | ||
Verify(msgs); | ||
|
||
// same message as before, but from another source and with valid sig | ||
AddMessage(msgs, 8, 8, 7, true); | ||
Verify(msgs); | ||
|
||
// same message as before, but from another source and signed with another key | ||
AddMessage(msgs, 9, 9, 7, true); | ||
Verify(msgs); | ||
|
||
msgs.clear(); | ||
// same message, signed by multiple keys | ||
AddMessage(msgs, 1, 1, 1, true); | ||
AddMessage(msgs, 1, 2, 1, true); | ||
AddMessage(msgs, 1, 3, 1, true); | ||
AddMessage(msgs, 2, 4, 1, true); | ||
AddMessage(msgs, 2, 5, 1, true); | ||
AddMessage(msgs, 2, 6, 1, true); | ||
Verify(msgs); | ||
|
||
// last message invalid from one source | ||
AddMessage(msgs, 1, 7, 1, false); | ||
Verify(msgs); | ||
} | ||
|
||
BOOST_AUTO_TEST_SUITE_END() |