2020-11-05 20:55:25 +00:00
|
|
|
import {expect} from "chai";
|
2020-11-19 14:41:45 +00:00
|
|
|
import {forEachImplementation} from "../switch";
|
|
|
|
import {getRandomBytes} from "../../src/helpers/utils";
|
|
|
|
|
|
|
|
function randomMessage(): Uint8Array {
|
|
|
|
return getRandomBytes(32);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getN<T>(n: number, getter: () => T): T[] {
|
|
|
|
return Array.from({length: n}, () => getter());
|
|
|
|
}
|
|
|
|
|
|
|
|
forEachImplementation((bls) => {
|
|
|
|
function getRandomData() {
|
|
|
|
const sk = bls.PrivateKey.fromKeygen();
|
|
|
|
const pk = sk.toPublicKey();
|
|
|
|
const msg = randomMessage();
|
|
|
|
const sig = sk.signMessage(msg);
|
|
|
|
return {sk, pk, msg, sig};
|
|
|
|
}
|
|
|
|
|
|
|
|
describe("verify", () => {
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should verify signature", () => {
|
2020-11-19 14:41:45 +00:00
|
|
|
const {pk, msg, sig} = getRandomData();
|
|
|
|
const pkHex = pk.toHex();
|
|
|
|
const isValid = bls.verify(pk.toBytes(), msg, sig.toBytes());
|
|
|
|
expect(isValid, "fail verify").to.be.true;
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
// Make sure to not modify original pubkey when verifying
|
|
|
|
expect(pk.toHex()).to.be.equal(pkHex, "pubkey modified when verifying");
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify empty signature", () => {
|
2020-11-19 14:41:45 +00:00
|
|
|
const {pk, msg} = getRandomData();
|
|
|
|
const emptySig = Buffer.alloc(96);
|
|
|
|
const isValid = bls.verify(pk.toBytes(), msg, emptySig);
|
|
|
|
expect(isValid).to.be.false;
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify signature of different message", () => {
|
2020-11-19 14:41:45 +00:00
|
|
|
const {pk, sig} = getRandomData();
|
|
|
|
const msg2 = randomMessage();
|
|
|
|
const isValid = bls.verify(pk.toBytes(), msg2, sig.toBytes());
|
|
|
|
expect(isValid).to.be.false;
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail verify signature signed by different key", () => {
|
2020-11-19 14:41:45 +00:00
|
|
|
const {msg, sig} = getRandomData();
|
|
|
|
const {pk: pk2} = getRandomData();
|
|
|
|
const isValid = bls.verify(pk2.toBytes(), msg, sig.toBytes());
|
|
|
|
expect(isValid).to.be.false;
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
describe("verify multiple", () => {
|
|
|
|
it(`should verify aggregated signatures`, () => {
|
|
|
|
const sks = getN(4, () => bls.PrivateKey.fromKeygen());
|
|
|
|
const msgs = getN(2, () => randomMessage());
|
|
|
|
const pks = sks.map((sk) => sk.toPublicKey());
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const sigs = [
|
|
|
|
sks[0].signMessage(msgs[0]),
|
|
|
|
sks[1].signMessage(msgs[0]),
|
|
|
|
sks[2].signMessage(msgs[1]),
|
|
|
|
sks[3].signMessage(msgs[1]),
|
|
|
|
];
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const aggPubkeys = [
|
|
|
|
bls.aggregatePubkeys([pks[0], pks[1]].map((pk) => pk.toBytes())),
|
|
|
|
bls.aggregatePubkeys([pks[2], pks[3]].map((pk) => pk.toBytes())),
|
|
|
|
];
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const aggSig = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
expect(bls.verifyMultiple(aggPubkeys, msgs, aggSig), "should be valid").to.be.true;
|
|
|
|
expect(bls.verifyMultiple(aggPubkeys.reverse(), msgs, aggSig), "should fail - swaped pubkeys").to.be.false;
|
|
|
|
});
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
it("should verify aggregated signatures - same message", () => {
|
|
|
|
const n = 4;
|
|
|
|
const msg = randomMessage();
|
|
|
|
const sks = getN(n, () => bls.PrivateKey.fromKeygen());
|
|
|
|
const pks = sks.map((sk) => sk.toPublicKey());
|
|
|
|
const sigs = sks.map((sk) => sk.signMessage(msg));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const aggregateSignature = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const isValid = bls.verifyMultiple(
|
|
|
|
pks.map((pk) => pk.toBytes()),
|
|
|
|
getN(4, () => msg), // Same message n times
|
2020-11-19 00:23:34 +00:00
|
|
|
aggregateSignature
|
2019-08-28 13:57:26 +00:00
|
|
|
);
|
2020-11-19 14:41:45 +00:00
|
|
|
expect(isValid).to.be.true;
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
|
2019-09-17 20:03:24 +00:00
|
|
|
it("should fail to verify aggregated signatures - no public keys", () => {
|
2020-11-19 14:41:45 +00:00
|
|
|
const sig = Buffer.alloc(96);
|
|
|
|
const msg1 = randomMessage();
|
|
|
|
const msg2 = randomMessage();
|
2019-08-05 15:48:26 +00:00
|
|
|
|
2020-11-19 14:41:45 +00:00
|
|
|
const isValid = bls.verifyMultiple([], [msg2, msg1], sig);
|
|
|
|
expect(isValid).to.be.false;
|
2019-08-05 15:48:26 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|