Update tests to run both implementations
This commit is contained in:
parent
57694c2e54
commit
f8cd6e7afa
|
@ -53,7 +53,6 @@
|
||||||
"@babel/preset-env": "^7.8.4",
|
"@babel/preset-env": "^7.8.4",
|
||||||
"@babel/preset-typescript": "^7.8.3",
|
"@babel/preset-typescript": "^7.8.3",
|
||||||
"@babel/register": "^7.8.3",
|
"@babel/register": "^7.8.3",
|
||||||
"@chainsafe/as-sha256": "0.2.0",
|
|
||||||
"@chainsafe/eth2-spec-tests": "0.12.0",
|
"@chainsafe/eth2-spec-tests": "0.12.0",
|
||||||
"@chainsafe/lodestar-spec-test-util": "^0.5.0",
|
"@chainsafe/lodestar-spec-test-util": "^0.5.0",
|
||||||
"@types/chai": "^4.2.9",
|
"@types/chai": "^4.2.9",
|
||||||
|
|
|
@ -43,7 +43,7 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer {
|
||||||
* @param signatures
|
* @param signatures
|
||||||
*/
|
*/
|
||||||
export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
|
export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
|
||||||
assert(signatures && signatures.length > 0, "EMPTY_AGGREGATE_ARRAY");
|
assert(signatures, "signatures is null or undefined");
|
||||||
const agg = Signature.aggregate(signatures.map((signature): Signature => Signature.fromBytes(signature)));
|
const agg = Signature.aggregate(signatures.map((signature): Signature => Signature.fromBytes(signature)));
|
||||||
return agg.toBytes();
|
return agg.toBytes();
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,8 @@ export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
|
||||||
*/
|
*/
|
||||||
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
|
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
|
||||||
assert(publicKeys, "publicKeys is null or undefined");
|
assert(publicKeys, "publicKeys is null or undefined");
|
||||||
if (publicKeys.length === 0) {
|
const agg = PublicKey.aggregate(publicKeys.map((pk) => PublicKey.fromBytes(pk)));
|
||||||
return Buffer.alloc(PUBLIC_KEY_LENGTH);
|
return agg.toBytes();
|
||||||
}
|
|
||||||
return publicKeys
|
|
||||||
.map((p) => PublicKey.fromBytes(toBuffer(p)))
|
|
||||||
.reduce((agg, pubKey) => agg.add(pubKey))
|
|
||||||
.toBytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,8 @@ export class PrivateKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromKeygen(entropy?: Uint8Array): PrivateKey {
|
static fromKeygen(entropy?: Uint8Array): PrivateKey {
|
||||||
return this.fromBytes(generateRandomSecretKey(Buffer.from(entropy)));
|
const sk = generateRandomSecretKey(entropy && Buffer.from(entropy));
|
||||||
|
return this.fromBytes(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(): SecretKeyType {
|
getValue(): SecretKeyType {
|
||||||
|
|
|
@ -24,6 +24,18 @@ export class PublicKey {
|
||||||
return this.fromBytes(hexToBytes(hex));
|
return this.fromBytes(hexToBytes(hex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static aggregate(pubkeys: PublicKey[]): PublicKey {
|
||||||
|
if (pubkeys.length === 0) {
|
||||||
|
throw Error("EMPTY_AGGREGATE_ARRAY");
|
||||||
|
}
|
||||||
|
|
||||||
|
const agg = new PublicKey(pubkeys[0].value.clone());
|
||||||
|
for (const pk of pubkeys.slice(1)) {
|
||||||
|
agg.value.add(pk.value);
|
||||||
|
}
|
||||||
|
return agg;
|
||||||
|
}
|
||||||
|
|
||||||
add(other: PublicKey): PublicKey {
|
add(other: PublicKey): PublicKey {
|
||||||
const agg = new PublicKey(this.value.clone());
|
const agg = new PublicKey(this.value.clone());
|
||||||
agg.value.add(other.value);
|
agg.value.add(other.value);
|
||||||
|
|
|
@ -28,6 +28,10 @@ export class Signature {
|
||||||
}
|
}
|
||||||
|
|
||||||
static aggregate(signatures: Signature[]): Signature {
|
static aggregate(signatures: Signature[]): Signature {
|
||||||
|
if (signatures.length === 0) {
|
||||||
|
throw Error("EMPTY_AGGREGATE_ARRAY");
|
||||||
|
}
|
||||||
|
|
||||||
const context = getContext();
|
const context = getContext();
|
||||||
const signature = new context.Signature();
|
const signature = new context.Signature();
|
||||||
signature.aggregate(signatures.map((sig) => sig.value));
|
signature.aggregate(signatures.map((sig) => sig.value));
|
||||||
|
|
|
@ -11,9 +11,9 @@ interface IAggregateSigsTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachImplementation((bls, implementation) => {
|
forEachImplementation((bls) => {
|
||||||
describeDirectorySpecTest<IAggregateSigsTestCase, string>(
|
describeDirectorySpecTest<IAggregateSigsTestCase, string>(
|
||||||
`${implementation} - bls/aggregate/small`,
|
"bls/aggregate/small",
|
||||||
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate/small"),
|
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate/small"),
|
||||||
(testCase) => {
|
(testCase) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -15,9 +15,9 @@ interface IAggregateSigsVerifyTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachImplementation((bls, implementation) => {
|
forEachImplementation((bls) => {
|
||||||
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
|
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
|
||||||
`${implementation} - bls/aggregate_verify/small`,
|
"bls/aggregate_verify/small",
|
||||||
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate_verify/small"),
|
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate_verify/small"),
|
||||||
(testCase) => {
|
(testCase) => {
|
||||||
const {pubkeys, messages, signature} = testCase.data.input;
|
const {pubkeys, messages, signature} = testCase.data.input;
|
||||||
|
|
|
@ -15,9 +15,9 @@ interface IAggregateSigsVerifyTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachImplementation((bls, implementation) => {
|
forEachImplementation((bls) => {
|
||||||
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
|
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
|
||||||
`${implementation} - bls/fast_aggregate_verify/small`,
|
"bls/fast_aggregate_verify/small",
|
||||||
path.join(SPEC_TESTS_DIR, "general/phase0/bls/fast_aggregate_verify/small"),
|
path.join(SPEC_TESTS_DIR, "general/phase0/bls/fast_aggregate_verify/small"),
|
||||||
(testCase) => {
|
(testCase) => {
|
||||||
const {pubkeys, message, signature} = testCase.data.input;
|
const {pubkeys, message, signature} = testCase.data.input;
|
||||||
|
|
|
@ -14,9 +14,9 @@ interface ISignMessageTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachImplementation((bls, implementation) => {
|
forEachImplementation((bls) => {
|
||||||
describeDirectorySpecTest<ISignMessageTestCase, string>(
|
describeDirectorySpecTest<ISignMessageTestCase, string>(
|
||||||
`${implementation} - bls/sign/small`,
|
"bls/sign/small",
|
||||||
path.join(SPEC_TESTS_DIR, "general/phase0/bls/sign/small"),
|
path.join(SPEC_TESTS_DIR, "general/phase0/bls/sign/small"),
|
||||||
(testCase) => {
|
(testCase) => {
|
||||||
const {privkey, message} = testCase.data.input;
|
const {privkey, message} = testCase.data.input;
|
||||||
|
|
|
@ -15,9 +15,9 @@ interface IVerifyTestCase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
forEachImplementation((bls, implementation) => {
|
forEachImplementation((bls) => {
|
||||||
describeDirectorySpecTest<IVerifyTestCase, boolean>(
|
describeDirectorySpecTest<IVerifyTestCase, boolean>(
|
||||||
`${implementation} - bls/verify/small`,
|
"bls/verify/small",
|
||||||
path.join(SPEC_TESTS_DIR, "general/phase0/bls/verify/small"),
|
path.join(SPEC_TESTS_DIR, "general/phase0/bls/verify/small"),
|
||||||
(testCase) => {
|
(testCase) => {
|
||||||
const {pubkey, message, signature} = testCase.data.input;
|
const {pubkey, message, signature} = testCase.data.input;
|
||||||
|
|
|
@ -17,14 +17,16 @@ export function forEachImplementation(
|
||||||
callback: (bls: ReturnType<typeof getBls>, implementation: Implementation) => void
|
callback: (bls: ReturnType<typeof getBls>, implementation: Implementation) => void
|
||||||
): void {
|
): void {
|
||||||
for (const implementation of implementations) {
|
for (const implementation of implementations) {
|
||||||
const bls = getBls(implementation);
|
describe(implementation, () => {
|
||||||
|
const bls = getBls(implementation);
|
||||||
|
|
||||||
if (implementation === "herumi") {
|
if (implementation === "herumi") {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await bls.initBLS();
|
await bls.initBLS();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(bls, implementation);
|
callback(bls, implementation);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,195 +1,105 @@
|
||||||
import {aggregatePubkeys, aggregateSignatures, initBLS, Keypair, verify, verifyMultiple} from "../../src";
|
|
||||||
import SHA256 from "@chainsafe/as-sha256";
|
|
||||||
import {expect} from "chai";
|
import {expect} from "chai";
|
||||||
|
import {forEachImplementation} from "../switch";
|
||||||
|
import {getRandomBytes} from "../../src/helpers/utils";
|
||||||
|
|
||||||
describe("test bls", function () {
|
function randomMessage(): Uint8Array {
|
||||||
before(async function () {
|
return getRandomBytes(32);
|
||||||
await initBLS();
|
}
|
||||||
});
|
|
||||||
|
|
||||||
describe("verify", function () {
|
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", () => {
|
||||||
it("should verify signature", () => {
|
it("should verify signature", () => {
|
||||||
const keypair = Keypair.generate();
|
const {pk, msg, sig} = getRandomData();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
|
const pkHex = pk.toHex();
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
const isValid = bls.verify(pk.toBytes(), msg, sig.toBytes());
|
||||||
const result = verify(keypair.publicKey.toBytes(), messageHash, signature.toBytes());
|
expect(isValid, "fail verify").to.be.true;
|
||||||
expect(result).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not modify original pubkey when verifying", () => {
|
// Make sure to not modify original pubkey when verifying
|
||||||
const keypair = Keypair.generate();
|
expect(pk.toHex()).to.be.equal(pkHex, "pubkey modified when verifying");
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
|
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
|
||||||
const pubKey = keypair.publicKey.toBytes();
|
|
||||||
verify(pubKey, messageHash, signature.toBytes());
|
|
||||||
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHex());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail verify empty signature", () => {
|
it("should fail verify empty signature", () => {
|
||||||
const keypair = Keypair.generate();
|
const {pk, msg} = getRandomData();
|
||||||
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
|
const emptySig = Buffer.alloc(96);
|
||||||
const signature = Buffer.alloc(96);
|
const isValid = bls.verify(pk.toBytes(), msg, emptySig);
|
||||||
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature);
|
expect(isValid).to.be.false;
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail verify signature of different message", () => {
|
it("should fail verify signature of different message", () => {
|
||||||
const keypair = Keypair.generate();
|
const {pk, sig} = getRandomData();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
const msg2 = randomMessage();
|
||||||
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
|
const isValid = bls.verify(pk.toBytes(), msg2, sig.toBytes());
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
expect(isValid).to.be.false;
|
||||||
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature.toBytes());
|
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail verify signature signed by different key", () => {
|
it("should fail verify signature signed by different key", () => {
|
||||||
const keypair = Keypair.generate();
|
const {msg, sig} = getRandomData();
|
||||||
const keypair2 = Keypair.generate();
|
const {pk: pk2} = getRandomData();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
const isValid = bls.verify(pk2.toBytes(), msg, sig.toBytes());
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
expect(isValid).to.be.false;
|
||||||
const result = verify(keypair2.publicKey.toBytes(), messageHash, signature.toBytes());
|
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("verify multiple", function () {
|
describe("verify multiple", () => {
|
||||||
it("should verify aggregated signatures", function () {
|
it(`should verify aggregated signatures`, () => {
|
||||||
this.timeout(5000);
|
const sks = getN(4, () => bls.PrivateKey.fromKeygen());
|
||||||
|
const msgs = getN(2, () => randomMessage());
|
||||||
|
const pks = sks.map((sk) => sk.toPublicKey());
|
||||||
|
|
||||||
const keypair1 = Keypair.generate();
|
const sigs = [
|
||||||
const keypair2 = Keypair.generate();
|
sks[0].signMessage(msgs[0]),
|
||||||
const keypair3 = Keypair.generate();
|
sks[1].signMessage(msgs[0]),
|
||||||
const keypair4 = Keypair.generate();
|
sks[2].signMessage(msgs[1]),
|
||||||
|
sks[3].signMessage(msgs[1]),
|
||||||
|
];
|
||||||
|
|
||||||
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
|
const aggPubkeys = [
|
||||||
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
|
bls.aggregatePubkeys([pks[0], pks[1]].map((pk) => pk.toBytes())),
|
||||||
|
bls.aggregatePubkeys([pks[2], pks[3]].map((pk) => pk.toBytes())),
|
||||||
|
];
|
||||||
|
|
||||||
const signature1 = keypair1.privateKey.signMessage(message1);
|
const aggSig = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
|
||||||
const signature2 = keypair2.privateKey.signMessage(message1);
|
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
|
||||||
|
|
||||||
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
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;
|
||||||
const aggregatePubKey34 = aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
|
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
|
||||||
signature1.toBytes(),
|
|
||||||
signature2.toBytes(),
|
|
||||||
signature3.toBytes(),
|
|
||||||
signature4.toBytes(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message1, message2], aggregateSignature);
|
|
||||||
|
|
||||||
expect(result).to.be.true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should verify aggregated signatures - same message", function () {
|
it("should verify aggregated signatures - same message", () => {
|
||||||
this.timeout(5000);
|
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));
|
||||||
|
|
||||||
const keypair1 = Keypair.generate();
|
const aggregateSignature = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
|
||||||
const keypair2 = Keypair.generate();
|
|
||||||
const keypair3 = Keypair.generate();
|
|
||||||
const keypair4 = Keypair.generate();
|
|
||||||
|
|
||||||
const message = Buffer.from(SHA256.digest(Buffer.from("Test1")));
|
const isValid = bls.verifyMultiple(
|
||||||
|
pks.map((pk) => pk.toBytes()),
|
||||||
const signature1 = keypair1.privateKey.signMessage(message);
|
getN(4, () => msg), // Same message n times
|
||||||
const signature2 = keypair2.privateKey.signMessage(message);
|
|
||||||
const signature3 = keypair3.privateKey.signMessage(message);
|
|
||||||
const signature4 = keypair4.privateKey.signMessage(message);
|
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
|
||||||
signature1.toBytes(),
|
|
||||||
signature2.toBytes(),
|
|
||||||
signature3.toBytes(),
|
|
||||||
signature4.toBytes(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const result = verifyMultiple(
|
|
||||||
[
|
|
||||||
keypair1.publicKey.toBytes(),
|
|
||||||
keypair2.publicKey.toBytes(),
|
|
||||||
keypair3.publicKey.toBytes(),
|
|
||||||
keypair4.publicKey.toBytes(),
|
|
||||||
],
|
|
||||||
[message, message, message, message],
|
|
||||||
aggregateSignature
|
aggregateSignature
|
||||||
);
|
);
|
||||||
|
expect(isValid).to.be.true;
|
||||||
expect(result).to.be.true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should fail to verify aggregated signatures - swapped messages", function () {
|
|
||||||
this.timeout(5000);
|
|
||||||
|
|
||||||
const keypair1 = Keypair.generate();
|
|
||||||
const keypair2 = Keypair.generate();
|
|
||||||
const keypair3 = Keypair.generate();
|
|
||||||
const keypair4 = Keypair.generate();
|
|
||||||
|
|
||||||
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
|
|
||||||
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
|
|
||||||
|
|
||||||
const signature1 = keypair1.privateKey.signMessage(message1);
|
|
||||||
const signature2 = keypair2.privateKey.signMessage(message1);
|
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
|
||||||
|
|
||||||
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
|
||||||
|
|
||||||
const aggregatePubKey34 = aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
|
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
|
||||||
signature1.toBytes(),
|
|
||||||
signature2.toBytes(),
|
|
||||||
signature3.toBytes(),
|
|
||||||
signature4.toBytes(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message2, message1], aggregateSignature);
|
|
||||||
|
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should fail to verify aggregated signatures - different pubkeys and messsages", () => {
|
|
||||||
const keypair1 = Keypair.generate();
|
|
||||||
const keypair2 = Keypair.generate();
|
|
||||||
const keypair3 = Keypair.generate();
|
|
||||||
const keypair4 = Keypair.generate();
|
|
||||||
|
|
||||||
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
|
|
||||||
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
|
|
||||||
|
|
||||||
const signature1 = keypair1.privateKey.signMessage(message1);
|
|
||||||
const signature2 = keypair2.privateKey.signMessage(message1);
|
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
|
||||||
|
|
||||||
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
|
||||||
signature1.toBytes(),
|
|
||||||
signature2.toBytes(),
|
|
||||||
signature3.toBytes(),
|
|
||||||
signature4.toBytes(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const result = verifyMultiple([aggregatePubKey12], [message2, message1], aggregateSignature);
|
|
||||||
|
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail to verify aggregated signatures - no public keys", () => {
|
it("should fail to verify aggregated signatures - no public keys", () => {
|
||||||
const signature = Buffer.alloc(96);
|
const sig = Buffer.alloc(96);
|
||||||
|
const msg1 = randomMessage();
|
||||||
|
const msg2 = randomMessage();
|
||||||
|
|
||||||
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
|
const isValid = bls.verifyMultiple([], [msg2, msg1], sig);
|
||||||
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
|
expect(isValid).to.be.false;
|
||||||
|
|
||||||
const result = verifyMultiple([], [message2, message1], signature);
|
|
||||||
|
|
||||||
expect(result).to.be.false;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import {PrivateKey, PublicKey, Keypair, destroy, initBLS} from "../../src";
|
|
||||||
import {expect} from "chai";
|
|
||||||
|
|
||||||
describe("keypair", function () {
|
|
||||||
before(async function () {
|
|
||||||
await initBLS();
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function () {
|
|
||||||
destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should create from private and public key", () => {
|
|
||||||
const secret = PrivateKey.fromKeygen();
|
|
||||||
const secret2 = PrivateKey.fromKeygen();
|
|
||||||
const publicKey = PublicKey.fromBytes(secret2.toPublicKey().toBytes());
|
|
||||||
const keypair = new Keypair(secret, publicKey);
|
|
||||||
expect(keypair.publicKey).to.be.equal(publicKey);
|
|
||||||
expect(keypair.privateKey).to.be.equal(secret);
|
|
||||||
expect(keypair.privateKey).to.not.be.equal(secret2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should create from private", () => {
|
|
||||||
const secret = PrivateKey.fromKeygen();
|
|
||||||
const publicKey = secret.toPublicKey();
|
|
||||||
const keypair = new Keypair(secret);
|
|
||||||
expect(keypair.publicKey.toBytes().toString("hex")).to.be.equal(publicKey.toBytes().toString("hex"));
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,36 +1,26 @@
|
||||||
import {PrivateKey, initBLS, destroy, SECRET_KEY_LENGTH} from "../../src";
|
|
||||||
import {expect} from "chai";
|
import {expect} from "chai";
|
||||||
|
import {forEachImplementation} from "../switch";
|
||||||
|
|
||||||
describe("privateKey", function () {
|
forEachImplementation((bls) => {
|
||||||
before(async function () {
|
describe("PrivateKey", () => {
|
||||||
await initBLS();
|
it("should generate fromKeygen private key", () => {
|
||||||
});
|
const privateKey1 = bls.PrivateKey.fromKeygen();
|
||||||
|
const privateKey2 = bls.PrivateKey.fromKeygen();
|
||||||
|
expect(privateKey1.toHex()).to.not.be.equal(privateKey2.toHex());
|
||||||
|
});
|
||||||
|
|
||||||
after(function () {
|
|
||||||
destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should generate fromKeygen private key", function () {
|
|
||||||
const privateKey1 = PrivateKey.fromKeygen();
|
|
||||||
const privateKey2 = PrivateKey.fromKeygen();
|
|
||||||
expect(privateKey1.toHex()).to.not.be.equal(privateKey2.toHex());
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should export private key to hex string", function () {
|
|
||||||
const privateKey = "0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
|
const privateKey = "0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
|
||||||
|
|
||||||
expect(PrivateKey.fromHex(privateKey).toHex()).to.be.equal(privateKey);
|
it("should export private key to hex string", () => {
|
||||||
|
expect(bls.PrivateKey.fromHex(privateKey).toHex()).to.be.equal(privateKey);
|
||||||
|
});
|
||||||
|
|
||||||
const privateKey2 = "07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
|
it("should export private key to hex string from non-prefixed hex", () => {
|
||||||
|
expect(bls.PrivateKey.fromHex(privateKey.replace("0x", "")).toHex()).to.be.equal(privateKey);
|
||||||
|
});
|
||||||
|
|
||||||
expect(PrivateKey.fromHex(privateKey2).toHex()).to.be.equal(privateKey);
|
it("should not accept too short private key", () => {
|
||||||
});
|
expect(() => bls.PrivateKey.fromHex("0x2123")).to.throw();
|
||||||
|
});
|
||||||
it("should export private key to bytes", function () {
|
|
||||||
expect(PrivateKey.fromKeygen().toBytes().length).to.be.equal(SECRET_KEY_LENGTH);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not accept too short private key", function () {
|
|
||||||
expect(() => PrivateKey.fromHex("0x2123")).to.throw();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,28 +1,21 @@
|
||||||
import {PublicKey, PrivateKey, initBLS, destroy} from "../../src";
|
|
||||||
import {expect} from "chai";
|
import {expect} from "chai";
|
||||||
|
import {forEachImplementation} from "../switch";
|
||||||
|
|
||||||
describe("public key", function () {
|
forEachImplementation((bls) => {
|
||||||
before(async function f() {
|
describe("PublicKey", () => {
|
||||||
await initBLS();
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function () {
|
|
||||||
destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("from hex", function () {
|
|
||||||
const publicKey =
|
const publicKey =
|
||||||
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
||||||
expect(PublicKey.fromHex(publicKey).toHex()).to.be.equal(publicKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("from bytes", function () {
|
it("should export public key to hex string", () => {
|
||||||
const publicKey =
|
expect(bls.PublicKey.fromHex(publicKey).toHex()).to.be.equal(publicKey);
|
||||||
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
});
|
||||||
expect(PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHex()).to.be.equal(`0x${publicKey}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("from private key", function () {
|
it("should export public key to hex string from non-prefixed hex", () => {
|
||||||
PrivateKey.fromKeygen().toPublicKey();
|
expect(bls.PublicKey.fromHex(publicKey.replace("0x", "")).toHex()).to.be.equal(publicKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("from private key", () => {
|
||||||
|
bls.PrivateKey.fromKeygen().toPublicKey();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
13
yarn.lock
13
yarn.lock
|
@ -2,11 +2,6 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@assemblyscript/loader@^0.9.2":
|
|
||||||
version "0.9.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.9.2.tgz#5e1563c9bb5839ff9c8b3ae667e9255d8a166a37"
|
|
||||||
integrity sha512-fSt+ARVyhRwtqYUcFaLP2LUQ3DRHTsE6V9I2Iw7xaxop1ryePEaCcctIzHspvthww/2RVgtBIbmf/ICDZWkcLw==
|
|
||||||
|
|
||||||
"@babel/cli@^7.8.4":
|
"@babel/cli@^7.8.4":
|
||||||
version "7.8.4"
|
version "7.8.4"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"
|
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"
|
||||||
|
@ -791,14 +786,6 @@
|
||||||
lodash "^4.17.13"
|
lodash "^4.17.13"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@chainsafe/as-sha256@0.2.0":
|
|
||||||
version "0.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.2.0.tgz#3ebe061d59d30af9e95a8c22ff4813cbf0e89dbc"
|
|
||||||
integrity sha512-reKklZhY4jSj7JdxdAjUfsaiMt2pdm8V/IqlOR5c4m6Y4tRCxt4f0HBMfyiE2ZQF4tqPPqRVf/ulXwK+LjLIxw==
|
|
||||||
dependencies:
|
|
||||||
"@assemblyscript/loader" "^0.9.2"
|
|
||||||
buffer "^5.4.3"
|
|
||||||
|
|
||||||
"@chainsafe/bls-hd-key@^0.1.0":
|
"@chainsafe/bls-hd-key@^0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@chainsafe/bls-hd-key/-/bls-hd-key-0.1.0.tgz#5e51de16801f4b4b421e418f0d1ef0692df0c585"
|
resolved "https://registry.yarnpkg.com/@chainsafe/bls-hd-key/-/bls-hd-key-0.1.0.tgz#5e51de16801f4b4b421e418f0d1ef0692df0c585"
|
||||||
|
|
Reference in New Issue