Run prettier

This commit is contained in:
Cayman 2020-11-04 11:40:36 -06:00
parent fd4c67b67d
commit c22069335f
No known key found for this signature in database
GPG Key ID: 54B21AEC3C53E1F5
19 changed files with 248 additions and 218 deletions

View File

@ -10,13 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [4.0.0] - 2020-08-31
### BREAKING CHANGES
* Signature.verifyAggregate now takes decompressed pubkeys instead of raw bytes of compressed key
- Signature.verifyAggregate now takes decompressed pubkeys instead of raw bytes of compressed key
## [3.0.0] - 2020-07-31
### BREAKING CHANGES
* Update bls-keygen to latest EIP-2333 standard ([55dd5d](https://github.com/chainsafe/bls/commit/55dd5d))
- Update bls-keygen to latest EIP-2333 standard ([55dd5d](https://github.com/chainsafe/bls/commit/55dd5d))
## [2.0.0] - 2020-05-21
@ -42,4 +43,5 @@ and [IETF draft bls specification](https://github.com/ethereum/eth2.0-specs/blob
## [0.2.2] - 2020-02-12
###Bugfixes:
- updated bls wasm binding version - it isn't catching unhandled rejections and modify stacktraces

View File

@ -8,17 +8,18 @@
This is a Javascript library that implements BLS (Boneh-Lynn-Shacham) signatures and supports signature aggregation.
| Version | Bls spec version |
|----------|:-------------:|
| 0.3.x | initial version |
| 1.x.x | draft #6 |
| 2.x.x | draft #7 |
| Version | Bls spec version |
| ------- | :--------------: |
| 0.3.x | initial version |
| 1.x.x | draft #6 |
| 2.x.x | draft #7 |
>[spec](https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#bls-signatures)
> [spec](https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#bls-signatures)
>[test vectors](https://github.com/ethereum/eth2.0-spec-tests/tree/master/tests/bls)
> [test vectors](https://github.com/ethereum/eth2.0-spec-tests/tree/master/tests/bls)
## Usage
- `yarn add @chainsafe/bls`
## License

View File

@ -4,7 +4,7 @@ import blsWasmWrapper from "@chainsafe/eth2-bls-wasm";
let blsWrapper: typeof blsWasmWrapper | null = null;
export async function init(): Promise<typeof blsWasmWrapper> {
if(blsWrapper) return blsWrapper;
if (blsWrapper) return blsWrapper;
await blsWasmWrapper.init();
blsWrapper = blsWasmWrapper;
return blsWrapper;
@ -14,8 +14,8 @@ export function destroy(): void {
blsWrapper = null;
}
export function getContext(): typeof blsWasmWrapper{
if(blsWrapper) {
export function getContext(): typeof blsWasmWrapper {
if (blsWrapper) {
return blsWrapper;
}
throw new Error("BLS not initialized");

View File

@ -1,5 +1,5 @@
import assert from "assert";
import {PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH} from "../constants";
import { PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH } from "../constants";
/**
* Pads byte array with zeroes on left side up to desired length.
@ -8,7 +8,10 @@ import {PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH} from "../constants";
* @param length
*/
export function padLeft(source: Uint8Array, length: number): Buffer {
assert(source.length <= length, "Given array must be smaller or equal to desired array size");
assert(
source.length <= length,
"Given array must be smaller or equal to desired array size"
);
const result = Buffer.alloc(length, 0);
result.set(source, length - source.length);
return result;

View File

@ -1,13 +1,13 @@
import {Keypair} from "./keypair";
import {PrivateKey} from "./privateKey";
import {PublicKey} from "./publicKey";
import {Signature} from "./signature";
import {PUBLIC_KEY_LENGTH} from "./constants";
import { Keypair } from "./keypair";
import { PrivateKey } from "./privateKey";
import { PublicKey } from "./publicKey";
import { Signature } from "./signature";
import { PUBLIC_KEY_LENGTH } from "./constants";
import assert from "assert";
export {Keypair, PrivateKey, PublicKey, Signature};
export { Keypair, PrivateKey, PublicKey, Signature };
export {init as initBLS} from "./context";
export { init as initBLS } from "./context";
function toBuffer(input: Uint8Array): Buffer {
return Buffer.from(input.buffer, input.byteOffset, input.length);
@ -47,11 +47,16 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer {
* @param signatures
*/
export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
assert(signatures && signatures.length > 0, "signatures is null or undefined or empty array");
assert(
signatures && signatures.length > 0,
"signatures is null or undefined or empty array"
);
return Signature.aggregate(
signatures.map((signature): Signature => {
return Signature.fromCompressedBytes(signature);
})
signatures.map(
(signature): Signature => {
return Signature.fromCompressedBytes(signature);
}
)
).toBytesCompressed();
}
@ -61,7 +66,7 @@ export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
*/
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
assert(publicKeys, "publicKeys is null or undefined");
if(publicKeys.length === 0) {
if (publicKeys.length === 0) {
return Buffer.alloc(PUBLIC_KEY_LENGTH);
}
return publicKeys
@ -76,14 +81,19 @@ export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
* @param messageHash
* @param signature
*/
export function verify(publicKey: Uint8Array, messageHash: Uint8Array, signature: Uint8Array): boolean {
export function verify(
publicKey: Uint8Array,
messageHash: Uint8Array,
signature: Uint8Array
): boolean {
assert(publicKey, "publicKey is null or undefined");
assert(messageHash, "messageHash is null or undefined");
assert(signature, "signature is null or undefined");
try {
return PublicKey
.fromBytes(publicKey)
.verifyMessage(Signature.fromCompressedBytes(toBuffer(signature)), toBuffer(messageHash));
return PublicKey.fromBytes(publicKey).verifyMessage(
Signature.fromCompressedBytes(toBuffer(signature)),
toBuffer(messageHash)
);
} catch (e) {
return false;
}
@ -95,14 +105,19 @@ export function verify(publicKey: Uint8Array, messageHash: Uint8Array, signature
* @param messageHash
* @param signature
*/
export function verifyAggregate(publicKeys: Uint8Array[], messageHash: Uint8Array, signature: Uint8Array): boolean {
export function verifyAggregate(
publicKeys: Uint8Array[],
messageHash: Uint8Array,
signature: Uint8Array
): boolean {
assert(publicKeys, "publicKey is null or undefined");
assert(messageHash, "messageHash is null or undefined");
assert(signature, "signature is null or undefined");
try {
return Signature
.fromCompressedBytes(signature)
.verifyAggregate(publicKeys.map(pubkey => PublicKey.fromBytes(pubkey)), messageHash);
return Signature.fromCompressedBytes(signature).verifyAggregate(
publicKeys.map((pubkey) => PublicKey.fromBytes(pubkey)),
messageHash
);
} catch (e) {
return false;
}
@ -125,17 +140,15 @@ export function verifyMultiple(
assert(messageHashes, "messageHash is null or undefined");
assert(signature, "signature is null or undefined");
if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) {
if (publicKeys.length === 0 || publicKeys.length != messageHashes.length) {
return false;
}
try {
return Signature
.fromCompressedBytes(toBuffer(signature))
.verifyMultiple(
publicKeys.map((key) => PublicKey.fromBytes(toBuffer(key))),
messageHashes.map((m) => toBuffer(m)),
fast
);
return Signature.fromCompressedBytes(toBuffer(signature)).verifyMultiple(
publicKeys.map((key) => PublicKey.fromBytes(toBuffer(key))),
messageHashes.map((m) => toBuffer(m)),
fast
);
} catch (e) {
return false;
}
@ -149,5 +162,5 @@ export default {
aggregatePubkeys,
verify,
verifyAggregate,
verifyMultiple
verifyMultiple,
};

View File

@ -1,16 +1,14 @@
import {PublicKey} from "./publicKey";
import {PrivateKey} from "./privateKey";
import { PublicKey } from "./publicKey";
import { PrivateKey } from "./privateKey";
export class Keypair {
private readonly _publicKey: PublicKey;
private readonly _privateKey: PrivateKey;
public constructor(privateKey: PrivateKey, publicKey?: PublicKey) {
this._privateKey = privateKey;
if(!publicKey) {
if (!publicKey) {
this._publicKey = PublicKey.fromPrivateKey(this._privateKey);
} else {
this._publicKey = publicKey;

View File

@ -1,13 +1,12 @@
import {SECRET_KEY_LENGTH} from "./constants";
import { SECRET_KEY_LENGTH } from "./constants";
import assert from "assert";
import {SecretKeyType} from "@chainsafe/eth2-bls-wasm";
import {generateRandomSecretKey} from "@chainsafe/bls-keygen";
import {getContext} from "./context";
import {PublicKey} from "./publicKey";
import {Signature} from "./signature";
import { SecretKeyType } from "@chainsafe/eth2-bls-wasm";
import { generateRandomSecretKey } from "@chainsafe/bls-keygen";
import { getContext } from "./context";
import { PublicKey } from "./publicKey";
import { Signature } from "./signature";
export class PrivateKey {
private value: SecretKeyType;
protected constructor(value: SecretKeyType) {
@ -15,7 +14,10 @@ export class PrivateKey {
}
public static fromBytes(bytes: Uint8Array): PrivateKey {
assert(bytes.length === SECRET_KEY_LENGTH, "Private key should have 32 bytes");
assert(
bytes.length === SECRET_KEY_LENGTH,
"Private key should have 32 bytes"
);
const context = getContext();
const secretKey = new context.SecretKey();
secretKey.deserialize(Buffer.from(bytes));
@ -24,7 +26,10 @@ export class PrivateKey {
public static fromHexString(value: string): PrivateKey {
value = value.replace("0x", "");
assert(value.length === SECRET_KEY_LENGTH * 2, "secret key must have 32 bytes");
assert(
value.length === SECRET_KEY_LENGTH * 2,
"secret key must have 32 bytes"
);
const context = getContext();
return new PrivateKey(context.deserializeHexStrToSecretKey(value));
}

View File

@ -1,13 +1,12 @@
import {PrivateKey} from "./privateKey";
import {PublicKeyType} from "@chainsafe/eth2-bls-wasm";
import {getContext} from "./context";
import {PUBLIC_KEY_LENGTH} from "./constants";
import { PrivateKey } from "./privateKey";
import { PublicKeyType } from "@chainsafe/eth2-bls-wasm";
import { getContext } from "./context";
import { PUBLIC_KEY_LENGTH } from "./constants";
import assert from "assert";
import {Signature} from "./signature";
import {EMPTY_PUBLIC_KEY} from "./helpers/utils";
import { Signature } from "./signature";
import { EMPTY_PUBLIC_KEY } from "./helpers/utils";
export class PublicKey {
private value: PublicKeyType;
protected constructor(value: PublicKeyType) {
@ -21,21 +20,17 @@ export class PublicKey {
public static fromBytes(bytes: Uint8Array): PublicKey {
const context = getContext();
const publicKey = new context.PublicKey();
if(!EMPTY_PUBLIC_KEY.equals(bytes)) {
if (!EMPTY_PUBLIC_KEY.equals(bytes)) {
publicKey.deserialize(bytes);
}
return new PublicKey(
publicKey
);
return new PublicKey(publicKey);
}
public static fromHex(value: string): PublicKey {
value = value.replace("0x", "");
assert(value.length === PUBLIC_KEY_LENGTH * 2);
const context = getContext();
return new PublicKey(
context.deserializeHexStrToPublicKey(value)
);
return new PublicKey(context.deserializeHexStrToPublicKey(value));
}
public static fromPublicKeyType(value: PublicKeyType): PublicKey {

View File

@ -1,12 +1,11 @@
import assert from "assert";
import {FP_POINT_LENGTH} from "./constants";
import {SignatureType} from "@chainsafe/eth2-bls-wasm";
import {getContext} from "./context";
import {PublicKey} from "./publicKey";
import {EMPTY_SIGNATURE} from "./helpers/utils";
import { FP_POINT_LENGTH } from "./constants";
import { SignatureType } from "@chainsafe/eth2-bls-wasm";
import { getContext } from "./context";
import { PublicKey } from "./publicKey";
import { EMPTY_SIGNATURE } from "./helpers/utils";
export class Signature {
private value: SignatureType;
protected constructor(value: SignatureType) {
@ -21,7 +20,7 @@ export class Signature {
);
const context = getContext();
const signature = new context.Signature();
if(!EMPTY_SIGNATURE.equals(value)) {
if (!EMPTY_SIGNATURE.equals(value)) {
signature.deserialize(value);
}
return new Signature(signature);
@ -35,33 +34,36 @@ export class Signature {
const context = getContext();
const signature = new context.Signature();
signature.aggregate(signatures.map((sig) => sig.getValue()));
return new Signature(
signature
);
return new Signature(signature);
}
public add(other: Signature): Signature {
const agg = this.value.clone();
agg.add(other.value);
return new Signature(
agg
);
return new Signature(agg);
}
public getValue(): SignatureType {
return this.value;
}
public verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean {
public verifyAggregate(
publicKeys: PublicKey[],
message: Uint8Array
): boolean {
return this.value.fastAggregateVerify(
publicKeys.map((key) => key.getValue()),
message
);
}
public verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[], fast = false): boolean {
public verifyMultiple(
publicKeys: PublicKey[],
messages: Uint8Array[],
fast = false
): boolean {
const msgs = Buffer.concat(messages);
if(!fast && !getContext().areAllMsgDifferent(msgs)) {
if (!fast && !getContext().areAllMsgDifferent(msgs)) {
return false;
}
return this.value.aggregateVerifyNoCheck(

View File

@ -1,6 +1,9 @@
import path from "path";
import bls, {initBLS} from "../../src";
import {describeDirectorySpecTest, InputType} from "@chainsafe/lodestar-spec-test-util";
import bls, { initBLS } from "../../src";
import {
describeDirectorySpecTest,
InputType,
} from "@chainsafe/lodestar-spec-test-util";
interface IAggregateSigsTestCase {
data: {
@ -19,23 +22,25 @@ describeDirectorySpecTest<IAggregateSigsTestCase, string>(
__dirname,
"../../node_modules/@chainsafe/eth2-spec-tests/tests/general/phase0/bls/aggregate/small"
),
(testCase => {
(testCase) => {
try {
const result = bls.aggregateSignatures(testCase.data.input.map(pubKey => {
return Buffer.from(pubKey.replace("0x", ""), "hex");
}));
const result = bls.aggregateSignatures(
testCase.data.input.map((pubKey) => {
return Buffer.from(pubKey.replace("0x", ""), "hex");
})
);
return `0x${result.toString("hex")}`;
} catch (e) {
if(e.message === "signatures is null or undefined or empty array") {
if (e.message === "signatures is null or undefined or empty array") {
return null;
}
throw e;
}
}),
},
{
inputTypes: {
data: InputType.YAML,
},
getExpected: (testCase => testCase.data.output)
getExpected: (testCase) => testCase.data.output,
}
);

View File

@ -1,6 +1,9 @@
import path from "path";
import bls, {initBLS} from "../../src";
import {describeDirectorySpecTest, InputType} from "@chainsafe/lodestar-spec-test-util";
import bls, { initBLS } from "../../src";
import {
describeDirectorySpecTest,
InputType,
} from "@chainsafe/lodestar-spec-test-util";
interface AggregateSigsVerifyTestCase {
data: {
@ -27,23 +30,23 @@ describeDirectorySpecTest<AggregateSigsVerifyTestCase, boolean>(
__dirname,
"../../node_modules/@chainsafe/eth2-spec-tests/tests/general/phase0/bls/aggregate_verify/small"
),
(testCase => {
const pubkeys = testCase.data.input.pubkeys.map(pubkey => {
(testCase) => {
const pubkeys = testCase.data.input.pubkeys.map((pubkey) => {
return Buffer.from(pubkey.replace("0x", ""), "hex");
});
const messages = testCase.data.input.messages.map(msg => {
const messages = testCase.data.input.messages.map((msg) => {
return Buffer.from(msg.replace("0x", ""), "hex");
});
return bls.verifyMultiple(
pubkeys,
messages,
Buffer.from(testCase.data.input.signature.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.signature.replace("0x", ""), "hex")
);
}),
},
{
inputTypes: {
data: InputType.YAML,
},
getExpected: (testCase => testCase.data.output)
getExpected: (testCase) => testCase.data.output,
}
);

View File

@ -1,6 +1,9 @@
import path from "path";
import bls, {initBLS} from "../../src";
import {describeDirectorySpecTest, InputType} from "@chainsafe/lodestar-spec-test-util";
import bls, { initBLS } from "../../src";
import {
describeDirectorySpecTest,
InputType,
} from "@chainsafe/lodestar-spec-test-util";
interface AggregateSigsVerifyTestCase {
data: {
@ -27,17 +30,19 @@ describeDirectorySpecTest<AggregateSigsVerifyTestCase, boolean>(
__dirname,
"../../node_modules/@chainsafe/eth2-spec-tests/tests/general/phase0/bls/fast_aggregate_verify/small"
),
(testCase => {
(testCase) => {
return bls.verifyAggregate(
testCase.data.input.pubkeys.map((key) => Buffer.from(key.replace("0x", ""), "hex")),
testCase.data.input.pubkeys.map((key) =>
Buffer.from(key.replace("0x", ""), "hex")
),
Buffer.from(testCase.data.input.message.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.signature.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.signature.replace("0x", ""), "hex")
);
}),
},
{
inputTypes: {
data: InputType.YAML,
},
getExpected: (testCase => testCase.data.output)
getExpected: (testCase) => testCase.data.output,
}
);

View File

@ -1,6 +1,9 @@
import path from "path";
import bls, {initBLS} from "../../src";
import {describeDirectorySpecTest, InputType} from "@chainsafe/lodestar-spec-test-util";
import bls, { initBLS } from "../../src";
import {
describeDirectorySpecTest,
InputType,
} from "@chainsafe/lodestar-spec-test-util";
interface ISignMessageTestCase {
data: {
@ -22,17 +25,17 @@ describeDirectorySpecTest<ISignMessageTestCase, string>(
__dirname,
"../../node_modules/@chainsafe/eth2-spec-tests/tests/general/phase0/bls/sign/small"
),
(testCase => {
const signature = bls.sign(
(testCase) => {
const signature = bls.sign(
Buffer.from(testCase.data.input.privkey.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.message.replace("0x", ""), "hex")
);
return `0x${signature.toString("hex")}`;
}),
},
{
inputTypes: {
data: InputType.YAML,
},
getExpected: (testCase => testCase.data.output)
getExpected: (testCase) => testCase.data.output,
}
);

View File

@ -1,6 +1,9 @@
import path from "path";
import bls, {initBLS} from "../../src";
import {describeDirectorySpecTest, InputType} from "@chainsafe/lodestar-spec-test-util";
import bls, { initBLS } from "../../src";
import {
describeDirectorySpecTest,
InputType,
} from "@chainsafe/lodestar-spec-test-util";
interface IVerifyTestCase {
data: {
@ -23,17 +26,17 @@ describeDirectorySpecTest<IVerifyTestCase, boolean>(
__dirname,
"../../node_modules/@chainsafe/eth2-spec-tests/tests/general/phase0/bls/verify/small"
),
(testCase => {
(testCase) => {
return bls.verify(
Buffer.from(testCase.data.input.pubkey.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.message.replace("0x", ""), "hex"),
Buffer.from(testCase.data.input.signature.replace("0x", ""), "hex")
);
}),
},
{
inputTypes: {
data: InputType.YAML,
},
getExpected: (testCase => testCase.data.output)
getExpected: (testCase) => testCase.data.output,
}
);

View File

@ -1,20 +1,19 @@
import {init, getContext, destroy} from "../../src/context";
import {expect} from "chai";
import { init, getContext, destroy } from "../../src/context";
import { expect } from "chai";
describe("bls wasm constext", function () {
afterEach(() => {
destroy();
});
it("initializes and works", async function () {
await init();
expect(getContext().getCurveOrder())
.to.be.equal("52435875175126190479447740508185965837690552500527637822603658699938581184513");
expect(getContext().getCurveOrder()).to.be.equal(
"52435875175126190479447740508185965837690552500527637822603658699938581184513"
);
});
it("throws if context not initialized", async function () {
expect(() => getContext().getCurveOrder()).to.throw();
});
});

View File

@ -1,12 +1,18 @@
import bls, {aggregatePubkeys, aggregateSignatures, initBLS, Keypair, verify, verifyMultiple} from "../../src";
import bls, {
aggregatePubkeys,
aggregateSignatures,
initBLS,
Keypair,
verify,
verifyMultiple,
} from "../../src";
import SHA256 from "@chainsafe/as-sha256";
import {expect} from "chai";
import {destroy} from "../../src/context";
import {padLeft} from "../../src/helpers/utils";
import { expect } from "chai";
import { destroy } from "../../src/context";
import { padLeft } from "../../src/helpers/utils";
describe("test bls", function () {
before(async function() {
before(async function () {
await initBLS();
});
@ -20,61 +26,57 @@ describe("test bls", function () {
});
});
describe("verify", function() {
describe("verify", function () {
it("should verify signature", () => {
const keypair = Keypair.generate();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
const signature = keypair.privateKey.signMessage(
messageHash,
);
const signature = keypair.privateKey.signMessage(messageHash);
const result = verify(
keypair.publicKey.toBytesCompressed(),
messageHash,
signature.toBytesCompressed(),
signature.toBytesCompressed()
);
expect(result).to.be.true;
});
it("should not modify original pubkey when verifying", () => {
const keypair = Keypair.generate();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
const signature = keypair.privateKey.signMessage(
messageHash,
);
const signature = keypair.privateKey.signMessage(messageHash);
const pubKey = keypair.publicKey.toBytesCompressed();
verify(
pubKey,
messageHash,
signature.toBytesCompressed(),
verify(pubKey, messageHash, signature.toBytesCompressed());
expect("0x" + pubKey.toString("hex")).to.be.equal(
keypair.publicKey.toHexString()
);
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHexString());
});
it("should fail verify empty signature", () => {
const keypair = Keypair.generate();
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
const messageHash2 = Buffer.from(
SHA256.digest(Buffer.from("Test message2"))
);
const signature = Buffer.alloc(96);
const result = verify(
keypair.publicKey.toBytesCompressed(),
messageHash2,
signature,
signature
);
expect(result).to.be.false;
});
it("should fail verify signature of different message", () => {
const keypair = Keypair.generate();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
const signature = keypair.privateKey.signMessage(
messageHash,
const messageHash = Buffer.from(
SHA256.digest(Buffer.from("Test message"))
);
const messageHash2 = Buffer.from(
SHA256.digest(Buffer.from("Test message2"))
);
const signature = keypair.privateKey.signMessage(messageHash);
const result = verify(
keypair.publicKey.toBytesCompressed(),
messageHash2,
signature.toBytesCompressed(),
signature.toBytesCompressed()
);
expect(result).to.be.false;
});
@ -82,26 +84,23 @@ describe("test bls", function () {
it("should fail verify signature signed by different key", () => {
const keypair = Keypair.generate();
const keypair2 = Keypair.generate();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
const signature = keypair.privateKey.signMessage(
messageHash,
const messageHash = Buffer.from(
SHA256.digest(Buffer.from("Test message"))
);
const signature = keypair.privateKey.signMessage(messageHash);
const result = verify(
keypair2.publicKey.toBytesCompressed(),
messageHash,
signature.toBytesCompressed(),
signature.toBytesCompressed()
);
expect(result).to.be.false;
});
});
describe("verify multiple", function() {
describe("verify multiple", function () {
it("should verify aggregated signatures", function () {
this.timeout(5000);
const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
@ -135,7 +134,7 @@ describe("test bls", function () {
const result = verifyMultiple(
[aggregatePubKey12, aggregatePubKey34],
[message1, message2],
aggregateSignature,
aggregateSignature
);
expect(result).to.be.true;
@ -144,8 +143,6 @@ describe("test bls", function () {
it("should verify aggregated signatures - same message", function () {
this.timeout(5000);
const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
@ -170,11 +167,11 @@ describe("test bls", function () {
keypair1.publicKey.toBytesCompressed(),
keypair2.publicKey.toBytesCompressed(),
keypair3.publicKey.toBytesCompressed(),
keypair4.publicKey.toBytesCompressed()
keypair4.publicKey.toBytesCompressed(),
],
[message, message, message, message],
aggregateSignature,
true,
true
);
expect(result).to.be.true;
@ -183,7 +180,6 @@ describe("test bls", function () {
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();
@ -217,15 +213,13 @@ describe("test bls", function () {
const result = bls.verifyMultiple(
[aggregatePubKey12, aggregatePubKey34],
[message2, message1],
aggregateSignature,
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();
@ -244,7 +238,6 @@ describe("test bls", function () {
keypair2.publicKey.toBytesCompressed(),
]);
const aggregateSignature = bls.aggregateSignatures([
signature1.toBytesCompressed(),
signature2.toBytesCompressed(),
@ -255,29 +248,21 @@ describe("test bls", function () {
const result = bls.verifyMultiple(
[aggregatePubKey12],
[message2, message1],
aggregateSignature,
aggregateSignature
);
expect(result).to.be.false;
});
it("should fail to verify aggregated signatures - no public keys", () => {
const signature = Buffer.alloc(96);
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const result = bls.verifyMultiple(
[],
[message2, message1],
signature,
);
const result = bls.verifyMultiple([], [message2, message1], signature);
expect(result).to.be.false;
});
});
});

View File

@ -1,9 +1,8 @@
import {PrivateKey,PublicKey,Keypair} from "../../src";
import {expect} from "chai";
import {destroy, init} from "../../src/context";
describe("keypair", function() {
import { PrivateKey, PublicKey, Keypair } from "../../src";
import { expect } from "chai";
import { destroy, init } from "../../src/context";
describe("keypair", function () {
before(async function () {
await init();
});
@ -15,7 +14,9 @@ describe("keypair", function() {
it("should create from private and public key", () => {
const secret = PrivateKey.random();
const secret2 = PrivateKey.random();
const publicKey = PublicKey.fromBytes(PublicKey.fromPrivateKey(secret2).toBytesCompressed());
const publicKey = PublicKey.fromBytes(
PublicKey.fromPrivateKey(secret2).toBytesCompressed()
);
const keypair = new Keypair(secret, publicKey);
expect(keypair.publicKey).to.be.equal(publicKey);
expect(keypair.privateKey).to.be.equal(secret);
@ -26,7 +27,8 @@ describe("keypair", function() {
const secret = PrivateKey.random();
const publicKey = PublicKey.fromPrivateKey(secret);
const keypair = new Keypair(secret);
expect(keypair.publicKey.toBytesCompressed().toString("hex"))
.to.be.equal(publicKey.toBytesCompressed().toString("hex"));
expect(keypair.publicKey.toBytesCompressed().toString("hex")).to.be.equal(
publicKey.toBytesCompressed().toString("hex")
);
});
});

View File

@ -1,10 +1,9 @@
import {PrivateKey} from "../../src";
import {expect} from "chai";
import {SECRET_KEY_LENGTH} from "../../src/constants";
import {destroy, init} from "../../src/context";
describe("privateKey", function() {
import { PrivateKey } from "../../src";
import { expect } from "chai";
import { SECRET_KEY_LENGTH } from "../../src/constants";
import { destroy, init } from "../../src/context";
describe("privateKey", function () {
before(async function () {
await init();
});
@ -16,17 +15,25 @@ describe("privateKey", function() {
it("should generate random private key", function () {
const privateKey1 = PrivateKey.random();
const privateKey2 = PrivateKey.random();
expect(privateKey1.toHexString()).to.not.be.equal(privateKey2.toHexString());
expect(privateKey1.toHexString()).to.not.be.equal(
privateKey2.toHexString()
);
});
it("should export private key to hex string", function () {
const privateKey = "0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
const privateKey =
"0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
expect(PrivateKey.fromHexString(privateKey).toHexString()).to.be.equal(privateKey);
expect(PrivateKey.fromHexString(privateKey).toHexString()).to.be.equal(
privateKey
);
const privateKey2 = "07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
const privateKey2 =
"07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
expect(PrivateKey.fromHexString(privateKey2).toHexString()).to.be.equal(privateKey);
expect(PrivateKey.fromHexString(privateKey2).toHexString()).to.be.equal(
privateKey
);
});
it("should export private key to bytes", function () {
@ -36,5 +43,4 @@ describe("privateKey", function() {
it("should not accept too short private key", function () {
expect(() => PrivateKey.fromHexString("0x2123")).to.throw();
});
});

View File

@ -1,9 +1,8 @@
import {destroy, init} from "../../src/context";
import {PublicKey, PrivateKey} from "../../src";
import {expect} from "chai";
import { destroy, init } from "../../src/context";
import { PublicKey, PrivateKey } from "../../src";
import { expect } from "chai";
describe("public key", function () {
before(async function f() {
await init();
});
@ -14,18 +13,19 @@ describe("public key", function () {
it("from hex", function () {
const publicKey =
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
expect(PublicKey.fromHex(publicKey).toHexString()).to.be.equal(publicKey);
});
it("from bytes", function () {
const publicKey =
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
expect(PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHexString()).to.be.equal(`0x${publicKey}`);
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
expect(
PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHexString()
).to.be.equal(`0x${publicKey}`);
});
it("from private key", function () {
PublicKey.fromPrivateKey(PrivateKey.random());
});
});