From 0fa37a45f7dd556d066240a7e02d08748e728ce3 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Mon, 19 Jul 2021 13:23:27 +0200 Subject: [PATCH] Tests: simple fixes in "Aggregated SSSS" section --- src/test.cpp | 59 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/src/test.cpp b/src/test.cpp index f9c4130fe..ef6e4d9b2 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1255,11 +1255,6 @@ TEST_CASE("Threshold Signatures") { std::vector verifVec; }; - struct RecvSigShare { - G2Element sig; - RawData msg; - }; - class Participant { public: // Unique identifier @@ -1271,7 +1266,6 @@ TEST_CASE("Threshold Signatures") { // Coefficients vectors std::vector sks; std::vector pks; - std::vector sigs; // Internal Shares std::map sksShares; std::map pksShares; @@ -1283,7 +1277,7 @@ TEST_CASE("Threshold Signatures") { PrivateKey aggrSk; // Map of received aggrSigs from each participant id. - std::map recvAggrSigs; + std::map recvAggrSigs; bool recvShareAndVerificationVector(RawData fromId, const PrivateKey& skShare, const std::vector& verifVec) { G1Element evalPubShare = bls::Threshold::PublicKeyShare(verifVec, Bytes(id)); @@ -1291,8 +1285,8 @@ TEST_CASE("Threshold Signatures") { recvShares.emplace(std::move(fromId), RecvShare{skShare, evalPubShare, verifVec}); return true; } - void recvAggrSigsFrom(RawData& fromId, G2Element aggrSig, vector msgHash) { - recvAggrSigs.emplace(fromId, RecvSigShare{aggrSig, std::move(msgHash)}); + void recvAggrSigsFrom(RawData& fromId, const G2Element& sigShare) { + recvAggrSigs.emplace(fromId, sigShare); } }; @@ -1392,26 +1386,19 @@ TEST_CASE("Threshold Signatures") { // Data to be signed. std::vector msgHash = getRandomSeed(); + for (auto& participant : participants) { - // Load SIG() polynomial coefficients vector - for (int i = 0; i < m; i++) { - PrivateKey sk = participant.sks[i]; - G1Element pk = participant.pks[i]; - G2Element sig = bls::Threshold::Sign(sk, Bytes(msgHash)); - participant.sigs.emplace_back(sig); - REQUIRE(bls::Threshold::Verify(pk, Bytes(msgHash), {sig})); - } + // Recover public-key share and check it correspond to the aggregated secret-key share + G1Element aggrPk = bls::Threshold::PublicKeyShare(finalVerifVector, Bytes(participant.id)); + REQUIRE(aggrPk == participant.aggrSk.GetG1Element()); + + // Validate signature share against public-key share + G2Element aggrSig = bls::Threshold::Sign(participant.aggrSk, Bytes(msgHash)); + REQUIRE(bls::Threshold::Verify(aggrPk, Bytes(msgHash), {aggrSig})); - // Send participant.aggrSk sig to every other participant. + // Send signature share to every other participant. for (int i = 0; i < n; i++) { - auto& recipient = participants[i]; - G2Element aggrSig = bls::Threshold::Sign(participant.aggrSk, Bytes(msgHash)); - // Recv aggrSig and validates that correspond to Pa() - // Let's check that Pa(id) == participant.aggrPk - G1Element aggrPk = bls::Threshold::PublicKeyShare(finalVerifVector, Bytes(participant.id)); - REQUIRE(aggrPk == participant.aggrSk.GetG1Element()); - REQUIRE(bls::Threshold::Verify(aggrPk, Bytes(msgHash), {aggrSig})); - recipient.recvAggrSigsFrom(participant.id, aggrSig, msgHash); + participants[i].recvAggrSigsFrom(participant.id, aggrSig); } } @@ -1420,9 +1407,13 @@ TEST_CASE("Threshold Signatures") { RawData random = getRandomSeed(); Participant p = participants[random[0] % participants.size()]; // Block two participants at random - std::vector blockedIds; - blockedIds.emplace_back(participants[random[1] % participants.size()].id); - blockedIds.emplace_back(participants[random[2] % participants.size()].id); + int randomIdx = random[1] % participants.size(); + int randomIdx2 = random[2] % participants.size(); + while (randomIdx == randomIdx2) { randomIdx2 = getRandomSeed()[0] % participants.size(); } + std::vector blockedIds = { + participants[randomIdx].id, + participants[randomIdx2].id + }; // Gather sigs and ids. std::vector aggrSigs; @@ -1430,9 +1421,11 @@ TEST_CASE("Threshold Signatures") { for (const auto& recvSigShare : p.recvAggrSigs) { if (std::find(blockedIds.begin(), blockedIds.end(), recvSigShare.first) != blockedIds.end()) continue; ids.emplace_back(recvSigShare.first); - aggrSigs.emplace_back(recvSigShare.second.sig); + aggrSigs.emplace_back(recvSigShare.second); } + REQUIRE(aggrSigs.size() == m); + G2Element freeCoefficientSigs = bls::Threshold::SignatureRecover(aggrSigs, ids); // This will validate against Pa(0)! G1Element freeCoefficientPks = finalVerifVector[0]; @@ -1450,6 +1443,12 @@ TEST_CASE("Threshold Signatures") { PrivateKey finalKey = bls::Threshold::PrivateKeyRecover(aggrKeys, ids3); REQUIRE(finalKey.GetG1Element() == freeCoefficientPks); REQUIRE(bls::Threshold::Sign(finalKey, Bytes(msgHash)) == freeCoefficientSigs); + + // Now let's modify one sig share, aggregate again, and check that verification fails + aggrSigs[0] += G2Element::Generator(); + G2Element freeCoefficientSigs2 = bls::Threshold::SignatureRecover(aggrSigs, ids); + REQUIRE(freeCoefficientSigs2.IsValid()); + REQUIRE(!bls::Threshold::Verify(freeCoefficientPks, Bytes(msgHash), freeCoefficientSigs2)); } } }