Skip to content

Commit

Permalink
Ak.infinity agg sig (#149)
Browse files Browse the repository at this point in the history
* Allow validation of infinity sig

* Try to fix test

* Allow aggregate signature verification for empty messages and keys. Test eval to G2Element::Infinit. Tighten argument checks.

* Deal with manylinux2010 centos regressions

Co-authored-by: Mariano Sorgente <[email protected]>
Co-authored-by: Gene Hoffman <[email protected]>
  • Loading branch information
3 people authored Dec 15, 2020
1 parent 5e1d392 commit 7c8cdcf
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 25 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Install cibuildwheel
run: |
python -m pip install --upgrade pip
python -m pip install cibuildwheel==1.6.4
python -m pip install cibuildwheel==1.7.1
- name: Lint source with flake8
run: |
Expand Down Expand Up @@ -73,7 +73,8 @@ jobs:
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2010
CIBW_ENVIRONMENT_LINUX: "PATH=/project/cmake-3.17.3-Linux-`uname -m`/bin:$PATH"
CIBW_BEFORE_ALL_LINUX: >
yum -y install lzip
yum -y install epel-release
&& yum -y install lzip
&& curl -L https://github.com/Kitware/CMake/releases/download/v3.17.3/cmake-3.17.3-Linux-`uname -m`.sh > cmake.sh
&& yes | sh cmake.sh | cat
&& rm -f /usr/bin/cmake && hash -r
Expand Down
5 changes: 5 additions & 0 deletions python-bindings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,16 @@ def test_readme():
assert ok


def test_aggregate_verify_zero_items():
assert AugSchemeMPL.aggregate_verify([], [], G2Element.infinity())


test_schemes()
test_elements()
test_vectors_invalid()
test_vectors_valid()
test_readme()
test_aggregate_verify_zero_items()

print("\nAll tests passed.")

Expand Down
92 changes: 69 additions & 23 deletions src/schemes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,40 @@ using std::string;
using std::vector;

namespace bls {

enum InvariantResult { BAD=false, GOOD=true, CONTINUE };

// Enforce argument invariants for Agg Sig Verification
InvariantResult VerifyAggregateSignatureArguments(
const vector<G1Element> &pubkeys,
const vector<vector<uint8_t>> &messages, // unhashed
const G2Element &signature)
{
int n = pubkeys.size();

if (n == 0) {
return (messages.empty() && signature == G2Element::Infinity() ? GOOD : BAD);
}
if (n != messages.size() || n <= 0) {
return BAD;
}
return CONTINUE;
}

InvariantResult VerifyAggregateSignatureArguments(
const vector<vector<uint8_t>> &pubkeys,
const vector<vector<uint8_t>> &messages, // unhashed
const vector<uint8_t> &signature)
{
vector<G1Element> pubkeyElements;
int n = pubkeys.size();
for (int i = 0; i < n; ++i) {
pubkeyElements.push_back(G1Element::FromBytes(pubkeys[i].data()));
}
G2Element signatureElement = G2Element::FromBytes(signature.data());
return VerifyAggregateSignatureArguments(pubkeyElements, messages, signatureElement);
}

/* These are all for the min-pubkey-size variant.
TODO : analogs for min-signature-size
*/
Expand Down Expand Up @@ -158,8 +192,10 @@ bool CoreMPL::AggregateVerify(
int dst_len)
{
int n = pubkeys.size();
if (n != messages.size() || n <= 0)
return false;
if (n <= 0 || n != messages.size()) {
return VerifyAggregateSignatureArguments(pubkeys, messages, signature);
}

vector<G1Element> pubkeyElements;
for (int i = 0; i < n; ++i) {
pubkeyElements.push_back(G1Element::FromBytes(pubkeys[i].data()));
Expand All @@ -177,8 +213,9 @@ bool CoreMPL::AggregateVerify(
int dst_len)
{
int n = pubkeys.size();
if (n != messages.size() || n <= 0)
return false;
if (n <= 0 || n != messages.size()) {
return VerifyAggregateSignatureArguments(pubkeys, messages, signature);
}

g1_t *g1s = new g1_t[n + 1];
g2_t *g2s = new g2_t[n + 1];
Expand Down Expand Up @@ -279,9 +316,10 @@ bool BasicSchemeMPL::AggregateVerify(
const vector<vector<uint8_t>> &messages,
const vector<uint8_t> &signature)
{
int n = messages.size();
if (n <= 0)
return false;
int n = pubkeys.size();
auto arg_check = VerifyAggregateSignatureArguments(pubkeys, messages, signature);
if (arg_check != CONTINUE) return arg_check;

std::set<vector<uint8_t>> s(messages.begin(), messages.end());
if (s.size() != n)
return false;
Expand All @@ -298,10 +336,10 @@ bool BasicSchemeMPL::AggregateVerify(
const vector<vector<uint8_t>> &messages,
const G2Element &signature)
{
int n = messages.size();
if (n <= 0) {
return false;
}
int n = pubkeys.size();
auto arg_check = VerifyAggregateSignatureArguments(pubkeys, messages, signature);
if (arg_check != CONTINUE) return arg_check;

std::set<vector<uint8_t>> s(messages.begin(), messages.end());
if (s.size() != n) {
return false;
Expand Down Expand Up @@ -385,9 +423,10 @@ bool AugSchemeMPL::AggregateVerify(
const vector<vector<uint8_t>> &messages,
const vector<uint8_t> &signature)
{
int n = messages.size();
if (n <= 0)
return false;
int n = pubkeys.size();
auto arg_check = VerifyAggregateSignatureArguments(pubkeys, messages, signature);
if (arg_check != CONTINUE) return arg_check;

vector<vector<uint8_t>> augMessages(n);
for (int i = 0; i < n; ++i) {
vector<uint8_t> aug(pubkeys[i]);
Expand All @@ -410,9 +449,10 @@ bool AugSchemeMPL::AggregateVerify(
const vector<vector<uint8_t>> &messages,
const G2Element &signature)
{
int n = messages.size();
if (n <= 0)
return false;
int n = pubkeys.size();
auto arg_check = VerifyAggregateSignatureArguments(pubkeys, messages, signature);
if (arg_check != CONTINUE) return arg_check;

vector<vector<uint8_t>> augMessages(n);
for (int i = 0; i < n; ++i) {
vector<uint8_t> aug(pubkeys[i].Serialize());
Expand Down Expand Up @@ -542,11 +582,16 @@ bool PopSchemeMPL::FastAggregateVerify(
const vector<uint8_t> &message,
const G2Element &signature)
{
G1Element pkagg = CoreMPL::Aggregate(pubkeys);

int n = pubkeys.size();
if (n <= 0)
return false;

G1Element pkagg = CoreMPL::Aggregate(pubkeys);
const vector<vector<uint8_t>> messages = { message };
const vector<G1Element> pkelements = { pkagg };

if (pubkeys.size() <= 0) return false;
auto arg_check = VerifyAggregateSignatureArguments(pkelements, messages, signature);
if (arg_check != CONTINUE) return arg_check;

return CoreMPL::Verify(
pkagg,
Expand All @@ -562,9 +607,10 @@ bool PopSchemeMPL::FastAggregateVerify(
const vector<uint8_t> &signature)
{
int n = pubkeys.size();
if (n <= 0) {
return false;
}
const vector<vector<uint8_t>> messages = { message };

if (pubkeys.size() <= 0) return false;

vector<G1Element> pkelements;
for (int i = 0; i < n; ++i) {
pkelements.push_back(G1Element::FromBytes(pubkeys[i].data()));
Expand Down
28 changes: 28 additions & 0 deletions src/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,34 @@ TEST_CASE("Signature tests")

REQUIRE(AugSchemeMPL::AggregateVerify(pks, ms, aggSig));
}

SECTION("Aggregate Verification of zero items with infinity should pass")
{
vector<G1Element> pks_as_g1;
vector<vector<uint8_t> > pks_as_bytes;
vector<vector<uint8_t> > msgs;
vector<G2Element> sigs;

sigs.push_back(G2Element::Infinity());
G2Element aggSig = AugSchemeMPL::Aggregate(sigs);

REQUIRE(aggSig.Serialize().size() != 0);
REQUIRE(aggSig == G2Element::Infinity());

REQUIRE(AugSchemeMPL::AggregateVerify(pks_as_g1, msgs, aggSig));
REQUIRE(AugSchemeMPL::AggregateVerify(pks_as_bytes, msgs, aggSig.Serialize()));

REQUIRE(BasicSchemeMPL::AggregateVerify(pks_as_g1, msgs, aggSig));
REQUIRE(BasicSchemeMPL::AggregateVerify(pks_as_bytes, msgs, aggSig.Serialize()));

// FastAggregateVerify takes one message, and requires at least one key
vector<uint8_t> msg;
REQUIRE(pks_as_g1.size() == 0);
REQUIRE(PopSchemeMPL::FastAggregateVerify(pks_as_g1, msg, aggSig) == false);
REQUIRE(pks_as_bytes.size() == 0);
REQUIRE(PopSchemeMPL::FastAggregateVerify(pks_as_bytes, msg, aggSig.Serialize()) == false);

}
}

TEST_CASE("Agg sks") {
Expand Down

0 comments on commit 7c8cdcf

Please sign in to comment.