2019-11-27 20:58:41 +00:00
|
|
|
import bls, {aggregatePubkeys, aggregateSignatures, initLibrary, Keypair, verify, verifyMultiple} from "../../src";
|
2019-09-17 20:03:24 +00:00
|
|
|
import {sha256} from "js-sha256";
|
2019-08-05 15:48:26 +00:00
|
|
|
import {expect} from "chai";
|
2019-11-27 20:58:41 +00:00
|
|
|
import {destroy} from "../../src/context";
|
|
|
|
import {padLeft} from "../../lib/helpers/utils";
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
describe("test bls", function () {
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
before(async function() {
|
|
|
|
await initLibrary();
|
|
|
|
});
|
|
|
|
|
|
|
|
after(function () {
|
|
|
|
destroy();
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
describe("aggregate pubkey", function () {
|
|
|
|
it("should aggregate empty array", function () {
|
2019-08-05 15:48:26 +00:00
|
|
|
expect(bls.aggregatePubkeys([])).to.not.throw;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
describe("verify", function() {
|
|
|
|
it("should verify signature", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const messageHash = Buffer.from(sha256.arrayBuffer("Test"));
|
|
|
|
const domain = Buffer.alloc(8, 1);
|
2019-11-27 20:58:41 +00:00
|
|
|
const signature = keypair.privateKey.signMessage(
|
|
|
|
messageHash,
|
|
|
|
domain
|
2019-08-05 15:48:26 +00:00
|
|
|
);
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair.publicKey.toBytesCompressed(),
|
|
|
|
messageHash,
|
|
|
|
signature.toBytesCompressed(),
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
expect(result).to.be.true;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should not modify original pubkey when verifying", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const messageHash = Buffer.from(sha256.arrayBuffer("Test"));
|
|
|
|
const domain = Buffer.alloc(8, 1);
|
2019-11-27 20:58:41 +00:00
|
|
|
const signature = keypair.privateKey.signMessage(
|
|
|
|
messageHash,
|
|
|
|
domain
|
2019-08-05 15:48:26 +00:00
|
|
|
);
|
|
|
|
const pubKey = keypair.publicKey.toBytesCompressed();
|
2019-11-27 20:58:41 +00:00
|
|
|
verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
pubKey,
|
|
|
|
messageHash,
|
|
|
|
signature.toBytesCompressed(),
|
|
|
|
domain
|
|
|
|
);
|
2019-09-17 20:03:24 +00:00
|
|
|
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHexString());
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify empty signature", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const messageHash2 = Buffer.from(sha256.arrayBuffer("Test message2"));
|
2019-09-17 20:03:24 +00:00
|
|
|
const domain = Buffer.from("01", "hex");
|
2019-08-05 15:48:26 +00:00
|
|
|
const signature = Buffer.alloc(96);
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair.publicKey.toBytesCompressed(),
|
|
|
|
messageHash2,
|
|
|
|
signature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify signature of different message", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const messageHash = Buffer.from(sha256.arrayBuffer("Test message"));
|
2019-08-28 13:57:26 +00:00
|
|
|
const messageHash2 = Buffer.from(sha256.arrayBuffer("Test message2"));
|
2019-11-27 20:58:41 +00:00
|
|
|
const domain = padLeft(Buffer.from("01", "hex"), 8);
|
|
|
|
const signature = keypair.privateKey.signMessage(
|
|
|
|
messageHash,
|
|
|
|
domain
|
2019-08-05 15:48:26 +00:00
|
|
|
);
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair.publicKey.toBytesCompressed(),
|
|
|
|
messageHash2,
|
|
|
|
signature.toBytesCompressed(),
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify signature of different domain", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const messageHash = Buffer.from(sha256.arrayBuffer("Test message"));
|
2019-11-27 20:58:41 +00:00
|
|
|
const domain = padLeft(Buffer.from("01", "hex"), 8);
|
|
|
|
const domain2 = padLeft(Buffer.from("02", "hex"), 8);
|
|
|
|
const signature = keypair.privateKey.signMessage(
|
|
|
|
messageHash,
|
|
|
|
domain
|
2019-08-05 15:48:26 +00:00
|
|
|
);
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair.publicKey.toBytesCompressed(),
|
|
|
|
messageHash,
|
|
|
|
signature.toBytesCompressed(),
|
|
|
|
domain2
|
|
|
|
);
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify signature signed by different key", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
const keypair = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const messageHash = Buffer.from(sha256.arrayBuffer("Test message"));
|
2019-09-17 20:03:24 +00:00
|
|
|
const domain = Buffer.from("01", "hex");
|
2019-11-27 20:58:41 +00:00
|
|
|
const signature = keypair.privateKey.signMessage(
|
|
|
|
messageHash,
|
|
|
|
domain
|
2019-08-05 15:48:26 +00:00
|
|
|
);
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verify(
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
messageHash,
|
|
|
|
signature.toBytesCompressed(),
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
describe("verify multiple", function() {
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should verify aggregated signatures", function () {
|
2019-08-28 13:57:26 +00:00
|
|
|
this.timeout(5000);
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
|
|
|
|
const keypair1 = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const keypair3 = Keypair.generate();
|
|
|
|
const keypair4 = Keypair.generate();
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message1 = Buffer.from(sha256.arrayBuffer("Test1"));
|
|
|
|
const message2 = Buffer.from(sha256.arrayBuffer("Test2"));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const signature1 = keypair1.privateKey.signMessage(message1, domain);
|
|
|
|
const signature2 = keypair2.privateKey.signMessage(message1, domain);
|
|
|
|
const signature3 = keypair3.privateKey.signMessage(message2, domain);
|
|
|
|
const signature4 = keypair4.privateKey.signMessage(message2, domain);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const aggregatePubKey12 = aggregatePubkeys([
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair1.publicKey.toBytesCompressed(),
|
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const aggregatePubKey34 = aggregatePubkeys([
|
2019-08-05 15:48:26 +00:00
|
|
|
keypair3.publicKey.toBytesCompressed(),
|
|
|
|
keypair4.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const aggregateSignature = aggregateSignatures([
|
2019-08-05 15:48:26 +00:00
|
|
|
signature1.toBytesCompressed(),
|
|
|
|
signature2.toBytesCompressed(),
|
|
|
|
signature3.toBytesCompressed(),
|
|
|
|
signature4.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verifyMultiple(
|
2019-08-05 15:48:26 +00:00
|
|
|
[aggregatePubKey12, aggregatePubKey34],
|
|
|
|
[message1, message2],
|
|
|
|
aggregateSignature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.true;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should verify aggregated signatures - same message", function () {
|
2019-08-28 13:57:26 +00:00
|
|
|
this.timeout(5000);
|
|
|
|
|
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
|
|
|
|
const keypair1 = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const keypair3 = Keypair.generate();
|
|
|
|
const keypair4 = Keypair.generate();
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message = Buffer.from(sha256.arrayBuffer("Test1"));
|
2019-08-28 13:57:26 +00:00
|
|
|
|
|
|
|
const signature1 = keypair1.privateKey.signMessage(message, domain);
|
|
|
|
const signature2 = keypair2.privateKey.signMessage(message, domain);
|
|
|
|
const signature3 = keypair3.privateKey.signMessage(message, domain);
|
|
|
|
const signature4 = keypair4.privateKey.signMessage(message, domain);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const aggregateSignature = aggregateSignatures([
|
2019-08-28 13:57:26 +00:00
|
|
|
signature1.toBytesCompressed(),
|
|
|
|
signature2.toBytesCompressed(),
|
|
|
|
signature3.toBytesCompressed(),
|
|
|
|
signature4.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const result = verifyMultiple(
|
2019-08-28 13:57:26 +00:00
|
|
|
[
|
|
|
|
keypair1.publicKey.toBytesCompressed(),
|
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
keypair3.publicKey.toBytesCompressed(),
|
|
|
|
keypair4.publicKey.toBytesCompressed()
|
|
|
|
],
|
|
|
|
[message, message, message, message],
|
|
|
|
aggregateSignature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.true;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail to verify aggregated signatures - swapped messages", function () {
|
2019-08-28 13:57:26 +00:00
|
|
|
this.timeout(5000);
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
|
|
|
|
const keypair1 = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const keypair3 = Keypair.generate();
|
|
|
|
const keypair4 = Keypair.generate();
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message1 = Buffer.from(sha256.arrayBuffer("Test1"));
|
|
|
|
const message2 = Buffer.from(sha256.arrayBuffer("Test2"));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const signature1 = keypair1.privateKey.signMessage(message1, domain);
|
|
|
|
const signature2 = keypair2.privateKey.signMessage(message1, domain);
|
|
|
|
const signature3 = keypair3.privateKey.signMessage(message2, domain);
|
|
|
|
const signature4 = keypair4.privateKey.signMessage(message2, domain);
|
|
|
|
|
|
|
|
const aggregatePubKey12 = bls.aggregatePubkeys([
|
|
|
|
keypair1.publicKey.toBytesCompressed(),
|
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const aggregatePubKey34 = bls.aggregatePubkeys([
|
|
|
|
keypair3.publicKey.toBytesCompressed(),
|
|
|
|
keypair4.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const aggregateSignature = bls.aggregateSignatures([
|
|
|
|
signature1.toBytesCompressed(),
|
|
|
|
signature2.toBytesCompressed(),
|
|
|
|
signature3.toBytesCompressed(),
|
|
|
|
signature4.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const result = bls.verifyMultiple(
|
|
|
|
[aggregatePubKey12, aggregatePubKey34],
|
|
|
|
[message2, message1],
|
|
|
|
aggregateSignature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail to verify aggregated signatures - different pubkeys and messsages", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
|
|
|
|
const keypair1 = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const keypair3 = Keypair.generate();
|
|
|
|
const keypair4 = Keypair.generate();
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message1 = Buffer.from(sha256.arrayBuffer("Test1"));
|
|
|
|
const message2 = Buffer.from(sha256.arrayBuffer("Test2"));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const signature1 = keypair1.privateKey.signMessage(message1, domain);
|
|
|
|
const signature2 = keypair2.privateKey.signMessage(message1, domain);
|
|
|
|
const signature3 = keypair3.privateKey.signMessage(message2, domain);
|
|
|
|
const signature4 = keypair4.privateKey.signMessage(message2, domain);
|
|
|
|
|
|
|
|
const aggregatePubKey12 = bls.aggregatePubkeys([
|
|
|
|
keypair1.publicKey.toBytesCompressed(),
|
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
const aggregateSignature = bls.aggregateSignatures([
|
|
|
|
signature1.toBytesCompressed(),
|
|
|
|
signature2.toBytesCompressed(),
|
|
|
|
signature3.toBytesCompressed(),
|
|
|
|
signature4.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const result = bls.verifyMultiple(
|
|
|
|
[aggregatePubKey12],
|
|
|
|
[message2, message1],
|
|
|
|
aggregateSignature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail to verify aggregated signatures - different domain", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
const domain2 = Buffer.alloc(8, 1);
|
|
|
|
|
|
|
|
const keypair1 = Keypair.generate();
|
|
|
|
const keypair2 = Keypair.generate();
|
|
|
|
const keypair3 = Keypair.generate();
|
|
|
|
const keypair4 = Keypair.generate();
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message1 = Buffer.from(sha256.arrayBuffer("Test1"));
|
|
|
|
const message2 = Buffer.from(sha256.arrayBuffer("Test2"));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const signature1 = keypair1.privateKey.signMessage(message1, domain);
|
|
|
|
const signature2 = keypair2.privateKey.signMessage(message1, domain);
|
|
|
|
const signature3 = keypair3.privateKey.signMessage(message2, domain2);
|
|
|
|
const signature4 = keypair4.privateKey.signMessage(message2, domain2);
|
|
|
|
|
|
|
|
const aggregatePubKey12 = bls.aggregatePubkeys([
|
|
|
|
keypair1.publicKey.toBytesCompressed(),
|
|
|
|
keypair2.publicKey.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
const aggregateSignature = bls.aggregateSignatures([
|
|
|
|
signature1.toBytesCompressed(),
|
|
|
|
signature2.toBytesCompressed(),
|
|
|
|
signature3.toBytesCompressed(),
|
|
|
|
signature4.toBytesCompressed(),
|
|
|
|
]);
|
|
|
|
|
|
|
|
const result = bls.verifyMultiple(
|
|
|
|
[aggregatePubKey12],
|
|
|
|
[message2, message1],
|
|
|
|
aggregateSignature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail to verify aggregated signatures - no public keys", () => {
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const domain = Buffer.alloc(8, 0);
|
|
|
|
|
|
|
|
const signature = Buffer.alloc(96);
|
|
|
|
|
2019-11-27 20:58:41 +00:00
|
|
|
const message1 = Buffer.from(sha256.arrayBuffer("Test1"));
|
|
|
|
const message2 = Buffer.from(sha256.arrayBuffer("Test2"));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
|
|
|
const result = bls.verifyMultiple(
|
|
|
|
[],
|
|
|
|
[message2, message1],
|
|
|
|
signature,
|
|
|
|
domain
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(result).to.be.false;
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|