From 0c0bfd532459a2b13de7020e6d12c188c0b73130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Mon, 12 Aug 2019 09:51:18 +0200 Subject: [PATCH 01/16] add proper bls exports --- package.json | 1 + src/@types/keccak256/index.d.ts | 5 ----- src/helpers/g1point.ts | 2 +- src/helpers/g2point.ts | 8 ++++---- src/index.ts | 31 +++++++++++++------------------ src/privateKey.ts | 4 ++-- src/publicKey.ts | 2 +- src/signature.ts | 2 +- src/types.ts | 9 --------- 9 files changed, 23 insertions(+), 41 deletions(-) delete mode 100644 src/@types/keccak256/index.d.ts delete mode 100644 src/types.ts diff --git a/package.json b/package.json index 812e47c..34da2a1 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "coverage": "codecov -F bls" }, "dependencies": { + "@chainsafe/eth2.0-types": "^0.1.0", "@chainsafe/milagro-crypto-js": "0.1.3", "assert": "^1.4.1", "js-sha256": "^0.9.0", diff --git a/src/@types/keccak256/index.d.ts b/src/@types/keccak256/index.d.ts deleted file mode 100644 index 75e63d9..0000000 --- a/src/@types/keccak256/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'keccak256' { - - export default function hash(a: Buffer | (Buffer | string | number)[]): Buffer; - -} diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 8e087b4..7133f3b 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -1,11 +1,11 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP} from "@chainsafe/milagro-crypto-js/src/ecp"; import ctx from "../ctx"; -import {bytes48} from "../types"; import assert from "assert"; import {calculateYFlag, getModulus} from "./utils"; import * as random from "secure-random"; import {FP_POINT_LENGTH} from "../constants"; +import {bytes48} from "@chainsafe/eth2.0-types"; export class G1point { diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index 2eaab98..e58d1ae 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,12 +1,12 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; -import {BLSDomain, bytes32, bytes96} from "../types"; import { sha256 } from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; import assert from "assert"; import {FP_POINT_LENGTH, G2_HASH_PADDING} from "../constants"; +import {bytes32, bytes48, Domain} from "@chainsafe/eth2.0-types"; export class G2point { @@ -37,7 +37,7 @@ export class G2point { return this.point; } - public toBytesCompressed(): Buffer { + public toBytesCompressed(): bytes48 { const xReBytes = Buffer.alloc(FP_POINT_LENGTH, 0); const xImBytes = Buffer.alloc(FP_POINT_LENGTH, 0); this.point.getX().getA().tobytearray(xReBytes, 0); @@ -58,7 +58,7 @@ export class G2point { ]); } - public static hashToG2(message: bytes32, domain: BLSDomain): G2point { + public static hashToG2(message: bytes32, domain: Domain): G2point { const padding = Buffer.alloc(G2_HASH_PADDING, 0); const xReBytes = Buffer.concat([ padding, @@ -94,7 +94,7 @@ export class G2point { return new G2point(G2point.scaleWithCofactor(G2point.normaliseY(point))); } - public static fromCompressedBytes(value: bytes96): G2point { + public static fromCompressedBytes(value: bytes48): G2point { assert(value.length === 2 * FP_POINT_LENGTH, 'Expected signature of 96 bytes'); value = Buffer.from(value); const xImBytes = value.slice(0, FP_POINT_LENGTH); diff --git a/src/index.ts b/src/index.ts index 31616a7..2888c71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,3 @@ -import { - BLSDomain, - BLSSecretKey, - BLSPubkey, - BLSSignature, - bytes32, - bytes8 -} from "./types"; import {Keypair} from "./keypair"; import {PrivateKey} from "./privateKey"; import {G2point} from "./helpers/g2point"; @@ -14,11 +6,14 @@ import {PublicKey} from "./publicKey"; import {Signature} from "./signature"; import {ElipticCurvePairing} from "./helpers/ec-pairing"; import ctx from "./ctx"; +import {BLSPubkey, BLSSecretKey, BLSSignature, bytes32, Domain} from "@chainsafe/eth2.0-types"; + +export {Keypair, PrivateKey, PublicKey, Signature}; /** * Generates new secret and public key */ -function generateKeyPair(): Keypair { +export function generateKeyPair(): Keypair { return Keypair.generate(); } @@ -26,7 +21,7 @@ function generateKeyPair(): Keypair { * Generates public key from given secret. * @param {BLSSecretKey} secretKey */ -function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { +export function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { const keypair = new Keypair(PrivateKey.fromBytes(secretKey)); return keypair.publicKey.toBytesCompressed(); } @@ -37,7 +32,7 @@ function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { * @param messageHash * @param domain */ -function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: BLSDomain): BLSSignature { +export function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: Domain): BLSSignature { const privateKey = PrivateKey.fromBytes(secretKey); const hash = G2point.hashToG2(messageHash, domain); return privateKey.sign(hash).toBytesCompressed(); @@ -47,9 +42,9 @@ function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: BLSDomain): * Compines all given signature into one. * @param signatures */ -function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { +export function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { return signatures.map((signature): Signature => { - return Signature.fromCompressedBytes(signature) + return Signature.fromCompressedBytes(signature); }).reduce((previousValue, currentValue): Signature => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -59,12 +54,12 @@ function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { * Combines all given public keys into single one * @param publicKeys */ -function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { +export function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { if(publicKeys.length === 0) { return new G1point(new ctx.ECP()).toBytesCompressed(); } return publicKeys.map((publicKey): G1point => { - return G1point.fromBytesCompressed(publicKey) + return G1point.fromBytesCompressed(publicKey); }).reduce((previousValue, currentValue): G1point => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -77,7 +72,7 @@ function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { * @param signature * @param domain */ -function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignature, domain: bytes8): boolean { +export function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignature, domain: Domain): boolean { try { const key = PublicKey.fromBytes(publicKey); const sig = Signature.fromCompressedBytes(signature); @@ -98,7 +93,7 @@ function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignat * @param signature * @param domain */ -function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[], signature: BLSSignature, domain: bytes8): boolean { +export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[], signature: BLSSignature, domain: Domain): boolean { if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) { return false; } @@ -129,4 +124,4 @@ export default { aggregatePubkeys, verify, verifyMultiple -} +}; diff --git a/src/privateKey.ts b/src/privateKey.ts index e99dba2..0bb4161 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -5,7 +5,7 @@ import ctx from "./ctx"; import {padLeft} from "./helpers/utils"; import {G2point} from "./helpers/g2point"; import * as random from "secure-random"; -import {BLSDomain, BLSSecretKey, bytes32} from "./types"; +import {BLSSecretKey, bytes32, Domain} from "@chainsafe/eth2.0-types"; export class PrivateKey { @@ -23,7 +23,7 @@ export class PrivateKey { return message.mul(this.value); } - public signMessage(message: bytes32, domain: BLSDomain): G2point { + public signMessage(message: bytes32, domain: Domain): G2point { return G2point.hashToG2(message, domain).mul(this.value); } diff --git a/src/publicKey.ts b/src/publicKey.ts index 6d734a1..3697aaf 100644 --- a/src/publicKey.ts +++ b/src/publicKey.ts @@ -1,6 +1,6 @@ import {G1point} from "./helpers/g1point"; import {PrivateKey} from "./privateKey"; -import {BLSPubkey} from "./types"; +import {BLSPubkey} from "@chainsafe/eth2.0-types"; export class PublicKey { diff --git a/src/signature.ts b/src/signature.ts index 89dee16..76a1a16 100644 --- a/src/signature.ts +++ b/src/signature.ts @@ -1,7 +1,7 @@ import {G2point} from "./helpers/g2point"; -import {BLSSignature} from "./types"; import assert from "assert"; import {FP_POINT_LENGTH} from "./constants"; +import {BLSSignature} from "@chainsafe/eth2.0-types"; export class Signature { diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 6a6346a..0000000 --- a/src/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type bytes8 = Buffer; -export type bytes32 = Buffer; -export type bytes48 = Buffer; -export type bytes96 = Buffer; - -export type BLSDomain = bytes8; -export type BLSPubkey = bytes48; -export type BLSSecretKey = bytes32; -export type BLSSignature = bytes96; From 0e856d82b54c5b33d041748d918b97e4159d02d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Mon, 12 Aug 2019 10:20:40 +0200 Subject: [PATCH 02/16] fix bls exports --- .babelrc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 633f93f..353bc18 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,8 @@ { - "extends": "../../.babelrc" + "extends": "../../.babelrc", + "plugins": [ + "@babel/proposal-class-properties", + "@babel/proposal-object-rest-spread", + "rewire-exports" + ] } From 7c7cfc332a77435b3e5be1d8b3e7f820afe78d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Fri, 16 Aug 2019 10:54:16 +0200 Subject: [PATCH 03/16] api configuration --- src/helpers/g1point.ts | 4 ++-- src/helpers/g2point.ts | 8 ++++---- src/helpers/utils.ts | 2 +- src/index.ts | 6 +++--- src/privateKey.ts | 2 +- src/web.ts | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 8e087b4..ff705d0 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -96,7 +96,7 @@ export class G1point { const x = new ctx.FP(point.getX()); const yneg = new ctx.FP(point.getY()); yneg.neg(); - point.setxy(x.redc(), yneg.redc()) + point.setxy(x.redc(), yneg.redc()); } return new G1point(point); @@ -115,7 +115,7 @@ export class G1point { random.randomBuffer(FP_POINT_LENGTH), 0 ) - ) + ); } while (ecp.is_infinity()); return new G1point(ecp); } diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index 2eaab98..0a0fc89 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,7 +1,7 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; import {BLSDomain, bytes32, bytes96} from "../types"; -import { sha256 } from 'js-sha256'; +import {sha256} from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; @@ -89,7 +89,7 @@ export class G2point { xRe.add(one); xRe.norm(); point = new ctx.ECP2(); - point.setx(new ctx.FP2(xRe, xIm)) + point.setx(new ctx.FP2(xRe, xIm)); } return new G2point(G2point.scaleWithCofactor(G2point.normaliseY(point))); } @@ -189,7 +189,7 @@ export class G2point { 0 ) ) - ) + ); } while (point.is_infinity()); return new G2point(point); } @@ -240,7 +240,7 @@ export class G2point { ) { const newPoint = new ctx.ECP2(); newPoint.setxy(point.getX(), yNeg); - return newPoint + return newPoint; } else { return point; } diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 4bac7ba..25f1367 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -23,7 +23,7 @@ export function getModulus(): BIG { 'hex' ), 0 - ) + ); } export function calculateYFlag(yIm: BIG): boolean { diff --git a/src/index.ts b/src/index.ts index 31616a7..812289a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,7 +49,7 @@ function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: BLSDomain): */ function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { return signatures.map((signature): Signature => { - return Signature.fromCompressedBytes(signature) + return Signature.fromCompressedBytes(signature); }).reduce((previousValue, currentValue): Signature => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -64,7 +64,7 @@ function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { return new G1point(new ctx.ECP()).toBytesCompressed(); } return publicKeys.map((publicKey): G1point => { - return G1point.fromBytesCompressed(publicKey) + return G1point.fromBytesCompressed(publicKey); }).reduce((previousValue, currentValue): G1point => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -129,4 +129,4 @@ export default { aggregatePubkeys, verify, verifyMultiple -} +}; diff --git a/src/privateKey.ts b/src/privateKey.ts index e99dba2..a4cbd4b 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -48,7 +48,7 @@ export class PrivateKey { ), 0 ) - ) + ); } public static fromHexString(value: string): PrivateKey { diff --git a/src/web.ts b/src/web.ts index 08397b6..519e5e3 100644 --- a/src/web.ts +++ b/src/web.ts @@ -1,8 +1,8 @@ -import bls from "./index" +import bls from "./index"; // eslint-disable-next-line @typescript-eslint/no-explicit-any // @ts-ignore (function (window: any) { - window.bls = bls + window.bls = bls; // @ts-ignore })(window); From 4fa5b9cddd29a1712acec1adf4c4b33f35cab4ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Fri, 16 Aug 2019 11:18:29 +0200 Subject: [PATCH 04/16] fix codeclimate issues --- src/helpers/g2point.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index 3634144..82e1155 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,7 +1,6 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; -import { sha256 } from 'js-sha256'; -import {BLSDomain, bytes32, bytes96} from "../types"; +import {sha256} from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; From 2b38c8750170d5aa8228418cb99645183d927456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Mon, 12 Aug 2019 09:51:18 +0200 Subject: [PATCH 05/16] add proper bls exports --- package.json | 1 + src/@types/keccak256/index.d.ts | 5 ----- src/helpers/g1point.ts | 2 +- src/helpers/g2point.ts | 8 ++++---- src/index.ts | 31 +++++++++++++------------------ src/privateKey.ts | 4 ++-- src/publicKey.ts | 2 +- src/signature.ts | 2 +- src/types.ts | 9 --------- 9 files changed, 23 insertions(+), 41 deletions(-) delete mode 100644 src/@types/keccak256/index.d.ts delete mode 100644 src/types.ts diff --git a/package.json b/package.json index 812e47c..34da2a1 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "coverage": "codecov -F bls" }, "dependencies": { + "@chainsafe/eth2.0-types": "^0.1.0", "@chainsafe/milagro-crypto-js": "0.1.3", "assert": "^1.4.1", "js-sha256": "^0.9.0", diff --git a/src/@types/keccak256/index.d.ts b/src/@types/keccak256/index.d.ts deleted file mode 100644 index 75e63d9..0000000 --- a/src/@types/keccak256/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'keccak256' { - - export default function hash(a: Buffer | (Buffer | string | number)[]): Buffer; - -} diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 8e087b4..7133f3b 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -1,11 +1,11 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP} from "@chainsafe/milagro-crypto-js/src/ecp"; import ctx from "../ctx"; -import {bytes48} from "../types"; import assert from "assert"; import {calculateYFlag, getModulus} from "./utils"; import * as random from "secure-random"; import {FP_POINT_LENGTH} from "../constants"; +import {bytes48} from "@chainsafe/eth2.0-types"; export class G1point { diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index 2eaab98..e58d1ae 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,12 +1,12 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; -import {BLSDomain, bytes32, bytes96} from "../types"; import { sha256 } from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; import assert from "assert"; import {FP_POINT_LENGTH, G2_HASH_PADDING} from "../constants"; +import {bytes32, bytes48, Domain} from "@chainsafe/eth2.0-types"; export class G2point { @@ -37,7 +37,7 @@ export class G2point { return this.point; } - public toBytesCompressed(): Buffer { + public toBytesCompressed(): bytes48 { const xReBytes = Buffer.alloc(FP_POINT_LENGTH, 0); const xImBytes = Buffer.alloc(FP_POINT_LENGTH, 0); this.point.getX().getA().tobytearray(xReBytes, 0); @@ -58,7 +58,7 @@ export class G2point { ]); } - public static hashToG2(message: bytes32, domain: BLSDomain): G2point { + public static hashToG2(message: bytes32, domain: Domain): G2point { const padding = Buffer.alloc(G2_HASH_PADDING, 0); const xReBytes = Buffer.concat([ padding, @@ -94,7 +94,7 @@ export class G2point { return new G2point(G2point.scaleWithCofactor(G2point.normaliseY(point))); } - public static fromCompressedBytes(value: bytes96): G2point { + public static fromCompressedBytes(value: bytes48): G2point { assert(value.length === 2 * FP_POINT_LENGTH, 'Expected signature of 96 bytes'); value = Buffer.from(value); const xImBytes = value.slice(0, FP_POINT_LENGTH); diff --git a/src/index.ts b/src/index.ts index 31616a7..2888c71 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,3 @@ -import { - BLSDomain, - BLSSecretKey, - BLSPubkey, - BLSSignature, - bytes32, - bytes8 -} from "./types"; import {Keypair} from "./keypair"; import {PrivateKey} from "./privateKey"; import {G2point} from "./helpers/g2point"; @@ -14,11 +6,14 @@ import {PublicKey} from "./publicKey"; import {Signature} from "./signature"; import {ElipticCurvePairing} from "./helpers/ec-pairing"; import ctx from "./ctx"; +import {BLSPubkey, BLSSecretKey, BLSSignature, bytes32, Domain} from "@chainsafe/eth2.0-types"; + +export {Keypair, PrivateKey, PublicKey, Signature}; /** * Generates new secret and public key */ -function generateKeyPair(): Keypair { +export function generateKeyPair(): Keypair { return Keypair.generate(); } @@ -26,7 +21,7 @@ function generateKeyPair(): Keypair { * Generates public key from given secret. * @param {BLSSecretKey} secretKey */ -function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { +export function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { const keypair = new Keypair(PrivateKey.fromBytes(secretKey)); return keypair.publicKey.toBytesCompressed(); } @@ -37,7 +32,7 @@ function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { * @param messageHash * @param domain */ -function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: BLSDomain): BLSSignature { +export function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: Domain): BLSSignature { const privateKey = PrivateKey.fromBytes(secretKey); const hash = G2point.hashToG2(messageHash, domain); return privateKey.sign(hash).toBytesCompressed(); @@ -47,9 +42,9 @@ function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: BLSDomain): * Compines all given signature into one. * @param signatures */ -function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { +export function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { return signatures.map((signature): Signature => { - return Signature.fromCompressedBytes(signature) + return Signature.fromCompressedBytes(signature); }).reduce((previousValue, currentValue): Signature => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -59,12 +54,12 @@ function aggregateSignatures(signatures: BLSSignature[]): BLSSignature { * Combines all given public keys into single one * @param publicKeys */ -function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { +export function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { if(publicKeys.length === 0) { return new G1point(new ctx.ECP()).toBytesCompressed(); } return publicKeys.map((publicKey): G1point => { - return G1point.fromBytesCompressed(publicKey) + return G1point.fromBytesCompressed(publicKey); }).reduce((previousValue, currentValue): G1point => { return previousValue.add(currentValue); }).toBytesCompressed(); @@ -77,7 +72,7 @@ function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { * @param signature * @param domain */ -function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignature, domain: bytes8): boolean { +export function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignature, domain: Domain): boolean { try { const key = PublicKey.fromBytes(publicKey); const sig = Signature.fromCompressedBytes(signature); @@ -98,7 +93,7 @@ function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignat * @param signature * @param domain */ -function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[], signature: BLSSignature, domain: bytes8): boolean { +export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[], signature: BLSSignature, domain: Domain): boolean { if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) { return false; } @@ -129,4 +124,4 @@ export default { aggregatePubkeys, verify, verifyMultiple -} +}; diff --git a/src/privateKey.ts b/src/privateKey.ts index e99dba2..0bb4161 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -5,7 +5,7 @@ import ctx from "./ctx"; import {padLeft} from "./helpers/utils"; import {G2point} from "./helpers/g2point"; import * as random from "secure-random"; -import {BLSDomain, BLSSecretKey, bytes32} from "./types"; +import {BLSSecretKey, bytes32, Domain} from "@chainsafe/eth2.0-types"; export class PrivateKey { @@ -23,7 +23,7 @@ export class PrivateKey { return message.mul(this.value); } - public signMessage(message: bytes32, domain: BLSDomain): G2point { + public signMessage(message: bytes32, domain: Domain): G2point { return G2point.hashToG2(message, domain).mul(this.value); } diff --git a/src/publicKey.ts b/src/publicKey.ts index 6d734a1..3697aaf 100644 --- a/src/publicKey.ts +++ b/src/publicKey.ts @@ -1,6 +1,6 @@ import {G1point} from "./helpers/g1point"; import {PrivateKey} from "./privateKey"; -import {BLSPubkey} from "./types"; +import {BLSPubkey} from "@chainsafe/eth2.0-types"; export class PublicKey { diff --git a/src/signature.ts b/src/signature.ts index 89dee16..76a1a16 100644 --- a/src/signature.ts +++ b/src/signature.ts @@ -1,7 +1,7 @@ import {G2point} from "./helpers/g2point"; -import {BLSSignature} from "./types"; import assert from "assert"; import {FP_POINT_LENGTH} from "./constants"; +import {BLSSignature} from "@chainsafe/eth2.0-types"; export class Signature { diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index 6a6346a..0000000 --- a/src/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type bytes8 = Buffer; -export type bytes32 = Buffer; -export type bytes48 = Buffer; -export type bytes96 = Buffer; - -export type BLSDomain = bytes8; -export type BLSPubkey = bytes48; -export type BLSSecretKey = bytes32; -export type BLSSignature = bytes96; From 05741442a02d3c2fd0956fa62b963c647cf8657d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Mon, 12 Aug 2019 10:20:40 +0200 Subject: [PATCH 06/16] fix bls exports --- .babelrc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.babelrc b/.babelrc index 633f93f..353bc18 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,8 @@ { - "extends": "../../.babelrc" + "extends": "../../.babelrc", + "plugins": [ + "@babel/proposal-class-properties", + "@babel/proposal-object-rest-spread", + "rewire-exports" + ] } From 80d07d780f130f556401148ae7d971df58797728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Fri, 16 Aug 2019 13:49:51 +0200 Subject: [PATCH 07/16] fix lint --- src/helpers/g1point.ts | 4 ++-- src/helpers/g2point.ts | 8 ++++---- src/helpers/utils.ts | 2 +- src/privateKey.ts | 2 +- src/web.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 7133f3b..60b0218 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -96,7 +96,7 @@ export class G1point { const x = new ctx.FP(point.getX()); const yneg = new ctx.FP(point.getY()); yneg.neg(); - point.setxy(x.redc(), yneg.redc()) + point.setxy(x.redc(), yneg.redc()); } return new G1point(point); @@ -115,7 +115,7 @@ export class G1point { random.randomBuffer(FP_POINT_LENGTH), 0 ) - ) + ); } while (ecp.is_infinity()); return new G1point(ecp); } diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index e58d1ae..82e1155 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,6 +1,6 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; -import { sha256 } from 'js-sha256'; +import {sha256} from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; @@ -89,7 +89,7 @@ export class G2point { xRe.add(one); xRe.norm(); point = new ctx.ECP2(); - point.setx(new ctx.FP2(xRe, xIm)) + point.setx(new ctx.FP2(xRe, xIm)); } return new G2point(G2point.scaleWithCofactor(G2point.normaliseY(point))); } @@ -189,7 +189,7 @@ export class G2point { 0 ) ) - ) + ); } while (point.is_infinity()); return new G2point(point); } @@ -240,7 +240,7 @@ export class G2point { ) { const newPoint = new ctx.ECP2(); newPoint.setxy(point.getX(), yNeg); - return newPoint + return newPoint; } else { return point; } diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts index 4bac7ba..25f1367 100644 --- a/src/helpers/utils.ts +++ b/src/helpers/utils.ts @@ -23,7 +23,7 @@ export function getModulus(): BIG { 'hex' ), 0 - ) + ); } export function calculateYFlag(yIm: BIG): boolean { diff --git a/src/privateKey.ts b/src/privateKey.ts index 0bb4161..e525a0c 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -48,7 +48,7 @@ export class PrivateKey { ), 0 ) - ) + ); } public static fromHexString(value: string): PrivateKey { diff --git a/src/web.ts b/src/web.ts index 08397b6..519e5e3 100644 --- a/src/web.ts +++ b/src/web.ts @@ -1,8 +1,8 @@ -import bls from "./index" +import bls from "./index"; // eslint-disable-next-line @typescript-eslint/no-explicit-any // @ts-ignore (function (window: any) { - window.bls = bls + window.bls = bls; // @ts-ignore })(window); From 75b9a3bedfaaab32eb350a45b2ff7a400a876096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Tue, 20 Aug 2019 11:09:44 +0200 Subject: [PATCH 08/16] bls benchmarks --- package.json | 6 ++- test/benchmarks/index.ts | 11 +++++ test/benchmarks/suites/index.ts | 5 ++ .../benchmarks/suites/signatureAggregation.ts | 39 +++++++++++++++ .../suites/verifyInValidSignature.ts | 42 ++++++++++++++++ .../verifyInvalidAggregatedSignature.ts | 48 +++++++++++++++++++ .../suites/verifyValidAggregatedSignature.ts | 48 +++++++++++++++++++ .../benchmarks/suites/verifyValidSignature.ts | 43 +++++++++++++++++ 8 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 test/benchmarks/index.ts create mode 100644 test/benchmarks/suites/index.ts create mode 100644 test/benchmarks/suites/signatureAggregation.ts create mode 100644 test/benchmarks/suites/verifyInValidSignature.ts create mode 100644 test/benchmarks/suites/verifyInvalidAggregatedSignature.ts create mode 100644 test/benchmarks/suites/verifyValidAggregatedSignature.ts create mode 100644 test/benchmarks/suites/verifyValidSignature.ts diff --git a/package.json b/package.json index 34da2a1..3488a5f 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "test:unit": "nyc --cache-dir .nyc_output/.cache -r lcov -e .ts mocha -r ./.babel-register 'test/unit/**/*.test.ts' && nyc report", "test:spec": "mocha -r ./.babel-register 'test/spec/**/*.test.ts'", "test": "yarn test:unit && yarn test:spec", - "coverage": "codecov -F bls" + "coverage": "codecov -F bls", + "benchmark": "node -r ./.babel-register test/benchmarks" }, "dependencies": { "@chainsafe/eth2.0-types": "^0.1.0", @@ -49,11 +50,12 @@ "@babel/preset-typescript": "^7.3.3", "@babel/register": "^7.0.0", "@babel/runtime": "^7.4.4", + "@chainsafe/benchmark-utils": "^0.1.0", "@chainsafe/eth2.0-spec-test-util": "^0.2.3", "@types/assert": "^1.4.2", "@types/chai": "^4.1.7", "@types/mocha": "^5.2.5", - "@types/node": "^10.12.17", + "@types/node": "^12.7.2", "@typescript-eslint/eslint-plugin": "^1.3.0", "@typescript-eslint/parser": "^1.3.0", "babel-plugin-rewire-exports": "^1.1.0", diff --git a/test/benchmarks/index.ts b/test/benchmarks/index.ts new file mode 100644 index 0000000..5b03fa5 --- /dev/null +++ b/test/benchmarks/index.ts @@ -0,0 +1,11 @@ +// Import benchmarks +import * as suites from "./suites"; +import {createReportDir, runSuite} from "@chainsafe/benchmark-utils"; +// Create file +const directory: string = createReportDir(); + + +// Run benchmarks +Object.values(suites).forEach((suite) => { + runSuite(suite(directory)); +}); \ No newline at end of file diff --git a/test/benchmarks/suites/index.ts b/test/benchmarks/suites/index.ts new file mode 100644 index 0000000..9af379d --- /dev/null +++ b/test/benchmarks/suites/index.ts @@ -0,0 +1,5 @@ +export {verifyInValidSignatureBenchmark} from './verifyInValidSignature'; +export {verifyValidSignatureBenchmark} from './verifyValidSignature'; +export {verifyValidAggregatedSignature} from './verifyValidAggregatedSignature'; +export {verifyInvalidAggregatedSignature} from './verifyInvalidAggregatedSignature'; +export {aggregateSignaturesBenchmark} from './signatureAggregation'; \ No newline at end of file diff --git a/test/benchmarks/suites/signatureAggregation.ts b/test/benchmarks/suites/signatureAggregation.ts new file mode 100644 index 0000000..ad58d51 --- /dev/null +++ b/test/benchmarks/suites/signatureAggregation.ts @@ -0,0 +1,39 @@ +/* eslint-disable @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires */ + +import {BenchSuite} from "@chainsafe/benchmark-utils"; +import {aggregateSignatures} from "../../../src"; + + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace global { + export let signatures: Buffer[]; + export let aggregateSignatures: Function; +} + +// @ts-ignore +global.require = require; + +global.aggregateSignatures = aggregateSignatures; + +export function aggregateSignaturesBenchmark(dir: string): BenchSuite { + + // Set the function test + const FUNCTION_NAME = "verifyValidSignature"; // PLEASE FILL THIS OUT + + const aggregateSignatures = function (): void { + global.aggregateSignatures(global.signatures); + }; + + return { + testFunctions: [aggregateSignatures], + setup: function() { + global.signatures = []; + const {Keypair} = require("../../../src"); + const {sha256} = require('js-sha256'); + const keypair = Keypair.generate(); + const message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + global.signatures.push(keypair.privateKey.signMessage(Buffer.from(message), Buffer.alloc(8)).toBytesCompressed()); + }, + file: dir + FUNCTION_NAME + ".txt" + }; +} \ No newline at end of file diff --git a/test/benchmarks/suites/verifyInValidSignature.ts b/test/benchmarks/suites/verifyInValidSignature.ts new file mode 100644 index 0000000..6cd4106 --- /dev/null +++ b/test/benchmarks/suites/verifyInValidSignature.ts @@ -0,0 +1,42 @@ +import {BenchSuite} from "@chainsafe/benchmark-utils"; +import {verify} from "../../../src"; + + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace global { + export let domain: Buffer; + export let message: Buffer; + export let signature: Buffer; + export let publicKey: Buffer; + export let verify: Function; +} + +// @ts-ignore +global.require = require; + +global.domain = Buffer.alloc(8); +global.verify = verify; + +export function verifyInValidSignatureBenchmark(dir: string): BenchSuite { + + // Set the function test + const FUNCTION_NAME = "verifyInValidSignature"; // PLEASE FILL THIS OUT + + const verifyInValidSignature = function (): void { + global.verify(global.publicKey, global.message, global.signature, global.domain); + }; + + return { + testFunctions: [verifyInValidSignature], + setup: function() { + const {Keypair} = require("../../../src"); + const {sha256} = require('js-sha256'); + const keypair = Keypair.generate(); + const keypair2 = Keypair.generate(); + global.publicKey = keypair2.publicKey.toBytesCompressed(); + global.message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + global.signature = keypair.privateKey.signMessage(Buffer.from(global.message), global.domain).toBytesCompressed(); + }, + file: dir + FUNCTION_NAME + ".txt" + }; +} \ No newline at end of file diff --git a/test/benchmarks/suites/verifyInvalidAggregatedSignature.ts b/test/benchmarks/suites/verifyInvalidAggregatedSignature.ts new file mode 100644 index 0000000..32e4a33 --- /dev/null +++ b/test/benchmarks/suites/verifyInvalidAggregatedSignature.ts @@ -0,0 +1,48 @@ +import {BenchSuite} from "@chainsafe/benchmark-utils"; +import {aggregateSignatures, verifyMultiple} from "../../../src"; + + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace global { + export let domain: Buffer; + export let messages: Buffer[]; + export let signature: Buffer; + export let publicKeys: Buffer[]; + export let verify: Function; +} + +// @ts-ignore +global.require = require; + +global.domain = Buffer.alloc(8); +global.verify = verifyMultiple; + +export function verifyInvalidAggregatedSignature(dir: string): BenchSuite { + + // Set the function test + const FUNCTION_NAME = "verifyInvalidAggregatedSignature"; // PLEASE FILL THIS OUT + + const verifyInvalidAggregatedSignature = function (): void { + global.verify(global.publicKeys, global.messages, global.signature, global.domain); + }; + + return { + testFunctions: [verifyInvalidAggregatedSignature], + setup: function() { + const {Keypair, aggregateSignatures} = require("../../../src"); + const {sha256} = require('js-sha256'); + const signatures = []; + global.publicKeys = []; + const message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + const message2 = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + for(let i = 0; i < 128; i++) { + const keypair = Keypair.generate(); + global.publicKeys.push(keypair.publicKey.toBytesCompressed()); + signatures.push(keypair.privateKey.signMessage(Buffer.from(message), global.domain).toBytesCompressed()); + } + global.messages = global.publicKeys.map(() => message2); + global.signature = aggregateSignatures(signatures); + }, + file: dir + FUNCTION_NAME + ".txt" + }; +} \ No newline at end of file diff --git a/test/benchmarks/suites/verifyValidAggregatedSignature.ts b/test/benchmarks/suites/verifyValidAggregatedSignature.ts new file mode 100644 index 0000000..b0efb17 --- /dev/null +++ b/test/benchmarks/suites/verifyValidAggregatedSignature.ts @@ -0,0 +1,48 @@ +import {BenchSuite} from "@chainsafe/benchmark-utils"; +import {aggregateSignatures, verifyMultiple} from "../../../src"; + + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace global { + export let domain: Buffer; + export let messages: Buffer[]; + export let signature: Buffer; + export let publicKeys: Buffer[]; + export let verify: Function; +} + +// @ts-ignore +global.require = require; + +global.domain = Buffer.alloc(8); +global.verify = verifyMultiple; + +export function verifyValidAggregatedSignature(dir: string): BenchSuite { + + // Set the function test + const FUNCTION_NAME = "verifyValidAggregatedSignature"; // PLEASE FILL THIS OUT + + const verifyValidAggregatedSignature = function (): void { + global.verify(global.publicKeys, global.messages, global.signature, global.domain); + }; + + return { + testFunctions: [verifyValidAggregatedSignature], + setup: function() { + const {Keypair, aggregateSignatures} = require("../../../src"); + const {sha256} = require('js-sha256'); + const signatures = []; + global.publicKeys = []; + const message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + for(let i = 0; i < 128; i++) { + const keypair = Keypair.generate(); + global.publicKeys.push(keypair.publicKey.toBytesCompressed()); + signatures.push(keypair.privateKey.signMessage(Buffer.from(message), global.domain).toBytesCompressed()); + } + global.messages = global.publicKeys.map(() => message); + global.signature = aggregateSignatures(signatures); + global.publicKeys.map(() => message); + }, + file: dir + FUNCTION_NAME + ".txt" + }; +} \ No newline at end of file diff --git a/test/benchmarks/suites/verifyValidSignature.ts b/test/benchmarks/suites/verifyValidSignature.ts new file mode 100644 index 0000000..a57d766 --- /dev/null +++ b/test/benchmarks/suites/verifyValidSignature.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires */ + +import {BenchSuite} from "@chainsafe/benchmark-utils"; +import {verify} from "../../../src"; + + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace global { + export let domain: Buffer; + export let message: Buffer; + export let signature: Buffer; + export let publicKey: Buffer; + export let verify: Function; +} + +// @ts-ignore +global.require = require; + +global.domain = Buffer.alloc(8); +global.verify = verify; + +export function verifyValidSignatureBenchmark(dir: string): BenchSuite { + + // Set the function test + const FUNCTION_NAME = "verifyValidSignature"; // PLEASE FILL THIS OUT + + const verifyValidSignature = function (): void { + global.verify(global.publicKey, global.message, global.signature, global.domain); + }; + + return { + testFunctions: [verifyValidSignature], + setup: function() { + const {Keypair} = require("../../../src"); + const {sha256} = require('js-sha256'); + const keypair = Keypair.generate(); + global.publicKey = keypair.publicKey.toBytesCompressed(); + global.message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); + global.signature = keypair.privateKey.signMessage(Buffer.from(global.message), global.domain).toBytesCompressed(); + }, + file: dir + FUNCTION_NAME + ".txt" + }; +} \ No newline at end of file From edf107045ad696bae1b4473862e2af230718a1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Wed, 28 Aug 2019 14:05:04 +0200 Subject: [PATCH 09/16] fix suite --- test/benchmarks/suites/index.ts | 8 ++++---- test/benchmarks/suites/verifyValidAggregatedSignature.ts | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/test/benchmarks/suites/index.ts b/test/benchmarks/suites/index.ts index 9af379d..1648eaf 100644 --- a/test/benchmarks/suites/index.ts +++ b/test/benchmarks/suites/index.ts @@ -1,5 +1,5 @@ -export {verifyInValidSignatureBenchmark} from './verifyInValidSignature'; -export {verifyValidSignatureBenchmark} from './verifyValidSignature'; +// export {verifyInValidSignatureBenchmark} from './verifyInValidSignature'; +// export {verifyValidSignatureBenchmark} from './verifyValidSignature'; export {verifyValidAggregatedSignature} from './verifyValidAggregatedSignature'; -export {verifyInvalidAggregatedSignature} from './verifyInvalidAggregatedSignature'; -export {aggregateSignaturesBenchmark} from './signatureAggregation'; \ No newline at end of file +// export {verifyInvalidAggregatedSignature} from './verifyInvalidAggregatedSignature'; +// export {aggregateSignaturesBenchmark} from './signatureAggregation'; \ No newline at end of file diff --git a/test/benchmarks/suites/verifyValidAggregatedSignature.ts b/test/benchmarks/suites/verifyValidAggregatedSignature.ts index b0efb17..7636872 100644 --- a/test/benchmarks/suites/verifyValidAggregatedSignature.ts +++ b/test/benchmarks/suites/verifyValidAggregatedSignature.ts @@ -23,7 +23,7 @@ export function verifyValidAggregatedSignature(dir: string): BenchSuite { const FUNCTION_NAME = "verifyValidAggregatedSignature"; // PLEASE FILL THIS OUT const verifyValidAggregatedSignature = function (): void { - global.verify(global.publicKeys, global.messages, global.signature, global.domain); + console.log(global.verify(global.publicKeys, global.messages, global.signature, global.domain)); }; return { @@ -43,6 +43,8 @@ export function verifyValidAggregatedSignature(dir: string): BenchSuite { global.signature = aggregateSignatures(signatures); global.publicKeys.map(() => message); }, - file: dir + FUNCTION_NAME + ".txt" + file: dir + FUNCTION_NAME + ".txt", + // profile: true, + name: FUNCTION_NAME, }; } \ No newline at end of file From 84bf46cb589d9e27f4e8f8d1631d1486fca1e3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Wed, 28 Aug 2019 15:57:26 +0200 Subject: [PATCH 10/16] add faster signature verification --- src/helpers/g1point.ts | 14 +++++++++- src/index.ts | 60 ++++++++++++++++++++++++++++++----------- test/spec/spec-tests | 2 +- test/unit/index.test.ts | 48 ++++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 22 deletions(-) diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 7133f3b..7a52a5f 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -5,7 +5,7 @@ import assert from "assert"; import {calculateYFlag, getModulus} from "./utils"; import * as random from "secure-random"; import {FP_POINT_LENGTH} from "../constants"; -import {bytes48} from "@chainsafe/eth2.0-types"; +import {BLSPubkey, bytes48} from "@chainsafe/eth2.0-types"; export class G1point { @@ -28,6 +28,10 @@ export class G1point { return new G1point(sum); } + public addRaW(other: bytes48): G1point { + return this.add(G1point.fromBytesCompressed(other)); + } + public equal(other: G1point): boolean { return this.point.equals(other.point); } @@ -102,6 +106,14 @@ export class G1point { return new G1point(point); } + public static aggregate(values: bytes48[]): G1point { + return values.map((value) => { + return G1point.fromBytesCompressed(value); + }).reduce((previousValue, currentValue): G1point => { + return previousValue.add(currentValue); + }); + } + public static generator(): G1point { return new G1point(ctx.ECP.generator()); } diff --git a/src/index.ts b/src/index.ts index 2888c71..5a69466 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,11 +58,7 @@ export function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { if(publicKeys.length === 0) { return new G1point(new ctx.ECP()).toBytesCompressed(); } - return publicKeys.map((publicKey): G1point => { - return G1point.fromBytesCompressed(publicKey); - }).reduce((previousValue, currentValue): G1point => { - return previousValue.add(currentValue); - }).toBytesCompressed(); + return G1point.aggregate(publicKeys).toBytesCompressed(); } /** @@ -77,6 +73,8 @@ export function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BL const key = PublicKey.fromBytes(publicKey); const sig = Signature.fromCompressedBytes(signature); + key.getPoint().getPoint().affine(); + sig.getPoint().getPoint().affine(); const g1Generated = G1point.generator(); const e1 = ElipticCurvePairing.pair(key.getPoint(), G2point.hashToG2(messageHash, domain)); const e2 = ElipticCurvePairing.pair(g1Generated, sig.getPoint()); @@ -98,20 +96,50 @@ export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[] return false; } try { - const g1Generated = G1point.generator(); + const sig = Signature.fromCompressedBytes(signature).getPoint(); + sig.getPoint().affine(); + const eCombined = new ctx.FP12(1); - publicKeys.forEach((publicKey, index): void => { - const g2 = G2point.hashToG2(messageHashes[index], domain); - eCombined.mul( - ElipticCurvePairing.pair( - PublicKey.fromBytes(publicKey).getPoint(), - g2 - ) - ); - }); - const e2 = ElipticCurvePairing.pair(g1Generated, Signature.fromCompressedBytes(signature).getPoint()); + + const reduction = messageHashes.reduce((previous, current, index) => { + if(previous.hash && current.equals(previous.hash)) { + return { + hash: previous.hash, + publicKey: previous.publicKey ? + previous.publicKey.addRaW(publicKeys[index]) + : + G1point.fromBytesCompressed(publicKeys[index]), + }; + } else if(!!previous.hash) { + const g2 = G2point.hashToG2(previous.hash, domain); + eCombined.mul( + ElipticCurvePairing.pair( + previous.publicKey, + g2 + ) + ); + return {hash: current, publicKey: G1point.fromBytesCompressed(publicKeys[index])}; + } else { + return { + hash: current, + publicKey: G1point.fromBytesCompressed(publicKeys[index]) + }; + } + }, {hash: null, publicKey: null}); + + const g2Final = G2point.hashToG2(reduction.hash, domain); + const keyFinal = reduction.publicKey; + eCombined.mul( + ElipticCurvePairing.pair( + keyFinal, + g2Final + ) + ); + + const e2 = ElipticCurvePairing.pair(G1point.generator(), sig); return e2.equals(eCombined); } catch (e) { + console.log(e); return false; } } diff --git a/test/spec/spec-tests b/test/spec/spec-tests index 7567342..15a1d85 160000 --- a/test/spec/spec-tests +++ b/test/spec/spec-tests @@ -1 +1 @@ -Subproject commit 7567342c966c4e020f6ab3889f93cedb65ea9bfe +Subproject commit 15a1d85125682d3ffc09a1ee9639f46c4a1653f6 diff --git a/test/unit/index.test.ts b/test/unit/index.test.ts index a8416e4..ee819f2 100644 --- a/test/unit/index.test.ts +++ b/test/unit/index.test.ts @@ -1,6 +1,6 @@ import bls from "../../src"; import {Keypair} from "../../src/keypair"; -import { sha256 } from 'js-sha256'; +import {sha256} from 'js-sha256'; import {G2point} from "../../src/helpers/g2point"; import {expect} from "chai"; @@ -65,7 +65,7 @@ describe('test bls', function () { it('should fail verify signature of different message', () => { const keypair = Keypair.generate(); const messageHash = Buffer.from(sha256.arrayBuffer("Test message")); - const messageHash2 = Buffer.from(sha256.arrayBuffer("Test message2")) + const messageHash2 = Buffer.from(sha256.arrayBuffer("Test message2")); const domain = Buffer.from("01", 'hex'); const signature = keypair.privateKey.sign( G2point.hashToG2(messageHash, domain) @@ -117,7 +117,7 @@ describe('test bls', function () { describe('verify multiple', function() { it('should verify aggregated signatures', function () { - this.timeout(5000) + this.timeout(5000); const domain = Buffer.alloc(8, 0); @@ -162,8 +162,48 @@ describe('test bls', function () { expect(result).to.be.true; }); + it('should verify aggregated signatures - same message', function () { + 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(); + + const message = Buffer.from("Test1", 'utf-8'); + + 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); + + const aggregateSignature = bls.aggregateSignatures([ + signature1.toBytesCompressed(), + signature2.toBytesCompressed(), + signature3.toBytesCompressed(), + signature4.toBytesCompressed(), + ]); + + const result = bls.verifyMultiple( + [ + keypair1.publicKey.toBytesCompressed(), + keypair2.publicKey.toBytesCompressed(), + keypair3.publicKey.toBytesCompressed(), + keypair4.publicKey.toBytesCompressed() + ], + [message, message, message, message], + aggregateSignature, + domain + ); + + expect(result).to.be.true; + }); + it('should fail to verify aggregated signatures - swapped messages', function () { - this.timeout(5000) + this.timeout(5000); const domain = Buffer.alloc(8, 0); From 9f58dcb5447e300e5c9009aed192527d5bcb8c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Wed, 28 Aug 2019 16:28:17 +0200 Subject: [PATCH 11/16] some fixes --- .gitignore | 1 + .../suites/verifyValidAggregatedSignature.ts | 32 +++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 435d202..6da32d7 100644 --- a/.gitignore +++ b/.gitignore @@ -64,3 +64,4 @@ typings/ dist/ lib/ +benchmark-reports diff --git a/test/benchmarks/suites/verifyValidAggregatedSignature.ts b/test/benchmarks/suites/verifyValidAggregatedSignature.ts index 7636872..5bca5f1 100644 --- a/test/benchmarks/suites/verifyValidAggregatedSignature.ts +++ b/test/benchmarks/suites/verifyValidAggregatedSignature.ts @@ -1,5 +1,5 @@ import {BenchSuite} from "@chainsafe/benchmark-utils"; -import {aggregateSignatures, verifyMultiple} from "../../../src"; +import {aggregateSignatures, Keypair, verifyMultiple} from "../../../src"; // eslint-disable-next-line @typescript-eslint/no-namespace @@ -8,6 +8,7 @@ declare namespace global { export let messages: Buffer[]; export let signature: Buffer; export let publicKeys: Buffer[]; + export let keypairs: Keypair[]; export let verify: Function; } @@ -19,29 +20,34 @@ global.verify = verifyMultiple; export function verifyValidAggregatedSignature(dir: string): BenchSuite { + global.publicKeys = []; + global.keypairs = []; + for(let i = 0; i < 128; i++) { + const keypair = Keypair.generate(); + global.keypairs.push(keypair); + global.publicKeys.push(keypair.publicKey.toBytesCompressed()); + } + // Set the function test const FUNCTION_NAME = "verifyValidAggregatedSignature"; // PLEASE FILL THIS OUT const verifyValidAggregatedSignature = function (): void { - console.log(global.verify(global.publicKeys, global.messages, global.signature, global.domain)); + global.verify(global.publicKeys, global.messages, global.signature, global.domain) }; return { testFunctions: [verifyValidAggregatedSignature], setup: function() { - const {Keypair, aggregateSignatures} = require("../../../src"); - const {sha256} = require('js-sha256'); - const signatures = []; - global.publicKeys = []; + const sha256 = require('js-sha256'); + const {aggregateSignatures} = require("../../../src"); const message = Buffer.from(sha256.arrayBuffer(Math.random().toString(36))); - for(let i = 0; i < 128; i++) { - const keypair = Keypair.generate(); - global.publicKeys.push(keypair.publicKey.toBytesCompressed()); - signatures.push(keypair.privateKey.signMessage(Buffer.from(message), global.domain).toBytesCompressed()); - } - global.messages = global.publicKeys.map(() => message); + const signatures = []; + global.messages = []; + global.keypairs.forEach((keypair) => { + signatures.push(keypair.privateKey.signMessage(message, global.domain).toBytesCompressed()); + global.messages.push(message); + }); global.signature = aggregateSignatures(signatures); - global.publicKeys.map(() => message); }, file: dir + FUNCTION_NAME + ".txt", // profile: true, From 528a5ca61156f4abb6f5eedd55922b8b965b7618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Thu, 29 Aug 2019 14:14:46 +0200 Subject: [PATCH 12/16] addess PR issues --- src/helpers/g1point.ts | 2 +- src/index.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helpers/g1point.ts b/src/helpers/g1point.ts index 7a52a5f..75234fd 100644 --- a/src/helpers/g1point.ts +++ b/src/helpers/g1point.ts @@ -28,7 +28,7 @@ export class G1point { return new G1point(sum); } - public addRaW(other: bytes48): G1point { + public addRaw(other: bytes48): G1point { return this.add(G1point.fromBytesCompressed(other)); } diff --git a/src/index.ts b/src/index.ts index 5a69466..4f0e48c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -106,7 +106,7 @@ export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[] return { hash: previous.hash, publicKey: previous.publicKey ? - previous.publicKey.addRaW(publicKeys[index]) + previous.publicKey.addRaw(publicKeys[index]) : G1point.fromBytesCompressed(publicKeys[index]), }; @@ -139,7 +139,6 @@ export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[] const e2 = ElipticCurvePairing.pair(G1point.generator(), sig); return e2.equals(eCombined); } catch (e) { - console.log(e); return false; } } From 337fa5f9e0feed6c9251e665392060a59677e906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Thu, 29 Aug 2019 14:16:11 +0200 Subject: [PATCH 13/16] update spec tests ref --- test/spec/spec-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spec/spec-tests b/test/spec/spec-tests index 15a1d85..7567342 160000 --- a/test/spec/spec-tests +++ b/test/spec/spec-tests @@ -1 +1 @@ -Subproject commit 15a1d85125682d3ffc09a1ee9639f46c4a1653f6 +Subproject commit 7567342c966c4e020f6ab3889f93cedb65ea9bfe From 6f17cc349e0d9681bf14bd6262fcd33b5c010f02 Mon Sep 17 00:00:00 2001 From: austinabell Date: Tue, 3 Sep 2019 14:17:55 -0400 Subject: [PATCH 14/16] replace byte32 type on hashes to Hash --- src/helpers/g2point.ts | 6 +++--- src/index.ts | 8 ++++---- src/privateKey.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/helpers/g2point.ts b/src/helpers/g2point.ts index a41a519..d283721 100644 --- a/src/helpers/g2point.ts +++ b/src/helpers/g2point.ts @@ -1,12 +1,12 @@ import {BIG} from "@chainsafe/milagro-crypto-js/src/big"; import {ECP2} from "@chainsafe/milagro-crypto-js/src/ecp2"; -import { sha256 } from 'js-sha256'; +import {sha256} from 'js-sha256'; import ctx from "../ctx"; import * as random from "secure-random"; import {calculateYFlag, getModulus, padLeft} from "./utils"; import assert from "assert"; import {FP_POINT_LENGTH, G2_HASH_PADDING} from "../constants"; -import {bytes32, bytes48, Domain} from "@chainsafe/eth2.0-types"; +import {bytes48, Domain, Hash} from "@chainsafe/eth2.0-types"; export class G2point { @@ -58,7 +58,7 @@ export class G2point { ]); } - public static hashToG2(message: bytes32, domain: Domain): G2point { + public static hashToG2(message: Hash, domain: Domain): G2point { const padding = Buffer.alloc(G2_HASH_PADDING, 0); const xReBytes = Buffer.concat([ padding, diff --git a/src/index.ts b/src/index.ts index 2888c71..beac54e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import {PublicKey} from "./publicKey"; import {Signature} from "./signature"; import {ElipticCurvePairing} from "./helpers/ec-pairing"; import ctx from "./ctx"; -import {BLSPubkey, BLSSecretKey, BLSSignature, bytes32, Domain} from "@chainsafe/eth2.0-types"; +import {BLSPubkey, BLSSecretKey, BLSSignature, Domain, Hash} from "@chainsafe/eth2.0-types"; export {Keypair, PrivateKey, PublicKey, Signature}; @@ -32,7 +32,7 @@ export function generatePublicKey(secretKey: BLSSecretKey): BLSPubkey { * @param messageHash * @param domain */ -export function sign(secretKey: BLSSecretKey, messageHash: bytes32, domain: Domain): BLSSignature { +export function sign(secretKey: BLSSecretKey, messageHash: Hash, domain: Domain): BLSSignature { const privateKey = PrivateKey.fromBytes(secretKey); const hash = G2point.hashToG2(messageHash, domain); return privateKey.sign(hash).toBytesCompressed(); @@ -72,7 +72,7 @@ export function aggregatePubkeys(publicKeys: BLSPubkey[]): BLSPubkey { * @param signature * @param domain */ -export function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BLSSignature, domain: Domain): boolean { +export function verify(publicKey: BLSPubkey, messageHash: Hash, signature: BLSSignature, domain: Domain): boolean { try { const key = PublicKey.fromBytes(publicKey); const sig = Signature.fromCompressedBytes(signature); @@ -93,7 +93,7 @@ export function verify(publicKey: BLSPubkey, messageHash: bytes32, signature: BL * @param signature * @param domain */ -export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: bytes32[], signature: BLSSignature, domain: Domain): boolean { +export function verifyMultiple(publicKeys: BLSPubkey[], messageHashes: Hash[], signature: BLSSignature, domain: Domain): boolean { if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) { return false; } diff --git a/src/privateKey.ts b/src/privateKey.ts index e525a0c..329fe2d 100644 --- a/src/privateKey.ts +++ b/src/privateKey.ts @@ -5,7 +5,7 @@ import ctx from "./ctx"; import {padLeft} from "./helpers/utils"; import {G2point} from "./helpers/g2point"; import * as random from "secure-random"; -import {BLSSecretKey, bytes32, Domain} from "@chainsafe/eth2.0-types"; +import {BLSSecretKey, Hash, Domain} from "@chainsafe/eth2.0-types"; export class PrivateKey { @@ -23,7 +23,7 @@ export class PrivateKey { return message.mul(this.value); } - public signMessage(message: bytes32, domain: Domain): G2point { + public signMessage(message: Hash, domain: Domain): G2point { return G2point.hashToG2(message, domain).mul(this.value); } From 98ec4bb4028fbb7ba4a24aa6fb889463fe7800f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Wed, 4 Sep 2019 13:35:34 +0200 Subject: [PATCH 15/16] improve bls spec tests --- package.json | 5 ++-- test/spec/aggregate_pubkeys.test.ts | 30 ++++++++++----------- test/spec/aggregate_sigs.test.ts | 29 ++++++++++---------- test/spec/g2_compressed.test.ts | 32 +++++++++++----------- test/spec/g2_uncompressed.test.ts | 42 ++++++++++++++--------------- test/spec/priv_to_public.test.ts | 16 +++++------ test/spec/sign_message.test.ts | 26 +++++++++--------- test/spec/spec-tests | 1 - 8 files changed, 90 insertions(+), 91 deletions(-) delete mode 160000 test/spec/spec-tests diff --git a/package.json b/package.json index 3488a5f..80cc4b9 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,9 @@ "lint-fix": "eslint --ext .ts src/ --fix", "pretest": "yarn check-types", "prepublishOnly": "yarn build", - "test:unit": "nyc --cache-dir .nyc_output/.cache -r lcov -e .ts mocha -r ./.babel-register 'test/unit/**/*.test.ts' && nyc report", - "test:spec": "mocha -r ./.babel-register 'test/spec/**/*.test.ts'", + "test:unit": "nyc --cache-dir .nyc_output/.cache -r lcov -e .ts mocha --colors -r ./.babel-register 'test/unit/**/*.test.ts' && nyc report", + "test:spec": "mocha --colors -r ./.babel-register 'test/spec/**/*.test.ts'", + "test:spec-min": "yarn run test:spec", "test": "yarn test:unit && yarn test:spec", "coverage": "codecov -F bls", "benchmark": "node -r ./.babel-register test/benchmarks" diff --git a/test/spec/aggregate_pubkeys.test.ts b/test/spec/aggregate_pubkeys.test.ts index 775cb60..09a911f 100644 --- a/test/spec/aggregate_pubkeys.test.ts +++ b/test/spec/aggregate_pubkeys.test.ts @@ -1,21 +1,21 @@ import {join} from "path"; import {describeSpecTest} from "@chainsafe/eth2.0-spec-test-util"; import bls from "../../src"; -import {BLSSignature} from "../../src/types"; +import {BLSSignature} from "@chainsafe/eth2.0-types"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/aggregate_pubkeys/aggregate_pubkeys.yaml"), - bls.aggregatePubkeys, - ({input}) => { - const sigs: BLSSignature[] = []; - input.forEach((sig: string) => { - sigs.push(Buffer.from(sig.replace('0x', ''), 'hex')) - }); - return [ - sigs - ]; - }, - ({output}) => output, - (result) => `0x${result.toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/aggregate_pubkeys/aggregate_pubkeys.yaml"), + bls.aggregatePubkeys, + ({input}) => { + const sigs: BLSSignature[] = []; + input.forEach((sig: string) => { + sigs.push(Buffer.from(sig.replace('0x', ''), 'hex')); + }); + return [ + sigs + ]; + }, + ({output}) => output, + (result) => `0x${result.toString('hex')}`, + () => false, ); diff --git a/test/spec/aggregate_sigs.test.ts b/test/spec/aggregate_sigs.test.ts index 7abc949..4a494a2 100644 --- a/test/spec/aggregate_sigs.test.ts +++ b/test/spec/aggregate_sigs.test.ts @@ -1,22 +1,21 @@ import {join} from "path"; import {describeSpecTest} from "@chainsafe/eth2.0-spec-test-util"; import bls from "../../src"; -import {G2point} from "../../src/helpers/g2point"; import {BLSPubkey} from "../../src/types"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/aggregate_sigs/aggregate_sigs.yaml"), - bls.aggregateSignatures, - ({input}) => { - const pubKeys: BLSPubkey[] = []; - input.forEach((pubKey: string) => { - pubKeys.push(Buffer.from(pubKey.replace('0x', ''), 'hex')) - }); - return [ - pubKeys - ]; - }, - ({output}) => output, - (result) => `0x${result.toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/aggregate_sigs/aggregate_sigs.yaml"), + bls.aggregateSignatures, + ({input}) => { + const pubKeys: BLSPubkey[] = []; + input.forEach((pubKey: string) => { + pubKeys.push(Buffer.from(pubKey.replace('0x', ''), 'hex')); + }); + return [ + pubKeys + ]; + }, + ({output}) => output, + (result) => `0x${result.toString('hex')}`, + () => false, ); diff --git a/test/spec/g2_compressed.test.ts b/test/spec/g2_compressed.test.ts index 025d9ae..e0cf37f 100644 --- a/test/spec/g2_compressed.test.ts +++ b/test/spec/g2_compressed.test.ts @@ -4,20 +4,20 @@ import {padLeft} from "../../src/helpers/utils"; import {G2point} from "../../src/helpers/g2point"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/msg_hash_g2_compressed/g2_compressed.yaml"), - G2point.hashToG2, - ({input}) => { - const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); - return [ - Buffer.from(input.message.replace('0x', ''), 'hex'), - domain - ]; - }, - ({output}) => { - const xReExpected = padLeft(Buffer.from(output[0].replace('0x', ''), 'hex'), 48); - const xImExpected = padLeft(Buffer.from(output[1].replace('0x', ''), 'hex'), 48); - return '0x' + Buffer.concat([xReExpected, xImExpected]).toString('hex') - }, - (result:G2point) => `0x${result.toBytesCompressed().toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/msg_hash_g2_compressed/g2_compressed.yaml"), + G2point.hashToG2, + ({input}) => { + const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); + return [ + Buffer.from(input.message.replace('0x', ''), 'hex'), + domain + ]; + }, + ({output}) => { + const xReExpected = padLeft(Buffer.from(output[0].replace('0x', ''), 'hex'), 48); + const xImExpected = padLeft(Buffer.from(output[1].replace('0x', ''), 'hex'), 48); + return '0x' + Buffer.concat([xReExpected, xImExpected]).toString('hex'); + }, + (result: G2point) => `0x${result.toBytesCompressed().toString('hex')}`, + () => false, ); diff --git a/test/spec/g2_uncompressed.test.ts b/test/spec/g2_uncompressed.test.ts index 12896f9..ec9550b 100644 --- a/test/spec/g2_uncompressed.test.ts +++ b/test/spec/g2_uncompressed.test.ts @@ -4,25 +4,25 @@ import {padLeft} from "../../src/helpers/utils"; import {G2point} from "../../src/helpers/g2point"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/msg_hash_g2_uncompressed/g2_uncompressed.yaml"), - G2point.hashToG2, - ({input}) => { - const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); - return [ - Buffer.from(input.message.replace('0x', ''), 'hex'), - domain - ]; - }, - ({output}) => { - return '0x' + G2point.fromUncompressedInput( - Buffer.from(output[0][0].replace('0x', ''), 'hex'), - Buffer.from(output[0][1].replace('0x', ''), 'hex'), - Buffer.from(output[1][0].replace('0x', ''), 'hex'), - Buffer.from(output[1][1].replace('0x', ''), 'hex'), - Buffer.from(output[2][0].replace('0x', ''), 'hex'), - Buffer.from(output[2][1].replace('0x', ''), 'hex'), - ).toBytesCompressed().toString('hex'); - }, - (result:G2point) => `0x${result.toBytesCompressed().toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/msg_hash_g2_uncompressed/g2_uncompressed.yaml"), + G2point.hashToG2, + ({input}) => { + const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); + return [ + Buffer.from(input.message.replace('0x', ''), 'hex'), + domain + ]; + }, + ({output}) => { + return '0x' + G2point.fromUncompressedInput( + Buffer.from(output[0][0].replace('0x', ''), 'hex'), + Buffer.from(output[0][1].replace('0x', ''), 'hex'), + Buffer.from(output[1][0].replace('0x', ''), 'hex'), + Buffer.from(output[1][1].replace('0x', ''), 'hex'), + Buffer.from(output[2][0].replace('0x', ''), 'hex'), + Buffer.from(output[2][1].replace('0x', ''), 'hex'), + ).toBytesCompressed().toString('hex'); + }, + (result: G2point) => `0x${result.toBytesCompressed().toString('hex')}`, + () => false, ); diff --git a/test/spec/priv_to_public.test.ts b/test/spec/priv_to_public.test.ts index d193d0a..75b08f8 100644 --- a/test/spec/priv_to_public.test.ts +++ b/test/spec/priv_to_public.test.ts @@ -3,12 +3,12 @@ import {describeSpecTest} from "@chainsafe/eth2.0-spec-test-util"; import bls from "../../src"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/priv_to_pub/priv_to_pub.yaml"), - bls.generatePublicKey, - ({input}) => { - return [Buffer.from(input.replace('0x', ''), 'hex')]; - }, - ({output}) => output, - (result) => `0x${result.toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/priv_to_pub/priv_to_pub.yaml"), + bls.generatePublicKey, + ({input}) => { + return [Buffer.from(input.replace('0x', ''), 'hex')]; + }, + ({output}) => output, + (result) => `0x${result.toString('hex')}`, + () => false, ); diff --git a/test/spec/sign_message.test.ts b/test/spec/sign_message.test.ts index 446a6c4..1117838 100644 --- a/test/spec/sign_message.test.ts +++ b/test/spec/sign_message.test.ts @@ -4,17 +4,17 @@ import bls from "../../src"; import {padLeft} from "../../src/helpers/utils"; describeSpecTest( - join(__dirname, "./spec-tests/tests/bls/sign_msg/sign_msg.yaml"), - bls.sign, - ({input}) => { - const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); - return [ - Buffer.from(input.privkey.replace('0x', ''), 'hex'), - Buffer.from(input.message.replace('0x', ''), 'hex'), - domain - ]; - }, - ({output}) => output, - (result) => `0x${result.toString('hex')}`, - () => false, + join(__dirname, "../../../spec-test-cases/tests/bls/sign_msg/sign_msg.yaml"), + bls.sign, + ({input}) => { + const domain = padLeft(Buffer.from(input.domain.replace('0x', ''), 'hex'), 8); + return [ + Buffer.from(input.privkey.replace('0x', ''), 'hex'), + Buffer.from(input.message.replace('0x', ''), 'hex'), + domain + ]; + }, + ({output}) => output, + (result) => `0x${result.toString('hex')}`, + () => false, ); diff --git a/test/spec/spec-tests b/test/spec/spec-tests deleted file mode 160000 index 7567342..0000000 --- a/test/spec/spec-tests +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7567342c966c4e020f6ab3889f93cedb65ea9bfe From 72fc3219e294f221222794d2faa79fc02a4eefc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Petruni=C4=87?= Date: Wed, 4 Sep 2019 14:04:56 +0200 Subject: [PATCH 16/16] fix lodestar spec tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 80cc4b9..6846aa8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@chainsafe/bls", - "version": "0.1.6", + "version": "0.1.7", "description": "Implementation of bls signature verification for ethereum 2.0", "main": "lib/index.js", "types": "lib/index.d.ts",