Replace herumi src with BLST
This commit is contained in:
parent
f29898d9dc
commit
5b06e4f61e
|
@ -1,4 +1,5 @@
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
|
import crypto from "crypto";
|
||||||
import {PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH} from "../constants";
|
import {PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH} from "../constants";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,5 +15,17 @@ export function padLeft(source: Uint8Array, length: number): Buffer {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hexToBytes(hex: string): Uint8Array {
|
||||||
|
return Uint8Array.from(Buffer.from(hex.replace("0x", ""), "hex"));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bytesToHex(bytes: Uint8Array): string {
|
||||||
|
return "0x" + Buffer.from(bytes).toString("hex");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRandomBytes(size: number): Uint8Array {
|
||||||
|
return Uint8Array.from(crypto.randomBytes(size));
|
||||||
|
}
|
||||||
|
|
||||||
export const EMPTY_PUBLIC_KEY = Buffer.alloc(PUBLIC_KEY_LENGTH);
|
export const EMPTY_PUBLIC_KEY = Buffer.alloc(PUBLIC_KEY_LENGTH);
|
||||||
export const EMPTY_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH);
|
export const EMPTY_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH);
|
||||||
|
|
45
src/index.ts
45
src/index.ts
|
@ -27,7 +27,7 @@ export function generateKeyPair(): Keypair {
|
||||||
export function generatePublicKey(secretKey: Uint8Array): Buffer {
|
export function generatePublicKey(secretKey: Uint8Array): Buffer {
|
||||||
assert(secretKey, "secretKey is null or undefined");
|
assert(secretKey, "secretKey is null or undefined");
|
||||||
const keypair = new Keypair(PrivateKey.fromBytes(toBuffer(secretKey)));
|
const keypair = new Keypair(PrivateKey.fromBytes(toBuffer(secretKey)));
|
||||||
return keypair.publicKey.toBytesCompressed();
|
return keypair.publicKey.toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer {
|
||||||
assert(secretKey, "secretKey is null or undefined");
|
assert(secretKey, "secretKey is null or undefined");
|
||||||
assert(messageHash, "messageHash is null or undefined");
|
assert(messageHash, "messageHash is null or undefined");
|
||||||
const privateKey = PrivateKey.fromBytes(toBuffer(secretKey));
|
const privateKey = PrivateKey.fromBytes(toBuffer(secretKey));
|
||||||
return privateKey.signMessage(toBuffer(messageHash)).toBytesCompressed();
|
return privateKey.signMessage(toBuffer(messageHash)).toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,13 +48,14 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer {
|
||||||
*/
|
*/
|
||||||
export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
|
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(
|
// return Signature.aggregate(
|
||||||
signatures.map(
|
// signatures.map(
|
||||||
(signature): Signature => {
|
// (signature): Signature => {
|
||||||
return Signature.fromCompressedBytes(signature);
|
// return Signature.fromBytes(signature);
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
).toBytesCompressed();
|
// ).toBytes();
|
||||||
|
return Buffer.alloc(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,14 +63,8 @@ export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
|
||||||
* @param publicKeys
|
* @param publicKeys
|
||||||
*/
|
*/
|
||||||
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
|
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
|
||||||
assert(publicKeys, "publicKeys is null or undefined");
|
const agg = PublicKey.aggregate(publicKeys.map((p) => PublicKey.fromBytes(p)));
|
||||||
if (publicKeys.length === 0) {
|
return agg.toBytes();
|
||||||
return Buffer.alloc(PUBLIC_KEY_LENGTH);
|
|
||||||
}
|
|
||||||
return publicKeys
|
|
||||||
.map((p) => PublicKey.fromBytes(toBuffer(p)))
|
|
||||||
.reduce((agg, pubKey) => agg.add(pubKey))
|
|
||||||
.toBytesCompressed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +79,7 @@ export function verify(publicKey: Uint8Array, messageHash: Uint8Array, signature
|
||||||
assert(signature, "signature is null or undefined");
|
assert(signature, "signature is null or undefined");
|
||||||
try {
|
try {
|
||||||
return PublicKey.fromBytes(publicKey).verifyMessage(
|
return PublicKey.fromBytes(publicKey).verifyMessage(
|
||||||
Signature.fromCompressedBytes(toBuffer(signature)),
|
Signature.fromBytes(toBuffer(signature)),
|
||||||
toBuffer(messageHash)
|
toBuffer(messageHash)
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -103,7 +98,7 @@ export function verifyAggregate(publicKeys: Uint8Array[], messageHash: Uint8Arra
|
||||||
assert(messageHash, "messageHash is null or undefined");
|
assert(messageHash, "messageHash is null or undefined");
|
||||||
assert(signature, "signature is null or undefined");
|
assert(signature, "signature is null or undefined");
|
||||||
try {
|
try {
|
||||||
return Signature.fromCompressedBytes(signature).verifyAggregate(
|
return Signature.fromBytes(signature).verifyAggregate(
|
||||||
publicKeys.map((pubkey) => PublicKey.fromBytes(pubkey)),
|
publicKeys.map((pubkey) => PublicKey.fromBytes(pubkey)),
|
||||||
messageHash
|
messageHash
|
||||||
);
|
);
|
||||||
|
@ -119,12 +114,7 @@ export function verifyAggregate(publicKeys: Uint8Array[], messageHash: Uint8Arra
|
||||||
* @param signature
|
* @param signature
|
||||||
* @param fast Check if all messages are different
|
* @param fast Check if all messages are different
|
||||||
*/
|
*/
|
||||||
export function verifyMultiple(
|
export function verifyMultiple(publicKeys: Uint8Array[], messageHashes: Uint8Array[], signature: Uint8Array): boolean {
|
||||||
publicKeys: Uint8Array[],
|
|
||||||
messageHashes: Uint8Array[],
|
|
||||||
signature: Uint8Array,
|
|
||||||
fast = false
|
|
||||||
): boolean {
|
|
||||||
assert(publicKeys, "publicKey is null or undefined");
|
assert(publicKeys, "publicKey is null or undefined");
|
||||||
assert(messageHashes, "messageHash is null or undefined");
|
assert(messageHashes, "messageHash is null or undefined");
|
||||||
assert(signature, "signature is null or undefined");
|
assert(signature, "signature is null or undefined");
|
||||||
|
@ -133,10 +123,9 @@ export function verifyMultiple(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return Signature.fromCompressedBytes(toBuffer(signature)).verifyMultiple(
|
return Signature.fromBytes(toBuffer(signature)).verifyMultiple(
|
||||||
publicKeys.map((key) => PublicKey.fromBytes(toBuffer(key))),
|
publicKeys.map((key) => PublicKey.fromBytes(toBuffer(key))),
|
||||||
messageHashes.map((m) => toBuffer(m)),
|
messageHashes.map((m) => toBuffer(m))
|
||||||
fast
|
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class Keypair {
|
||||||
public constructor(privateKey: PrivateKey, publicKey?: PublicKey) {
|
public constructor(privateKey: PrivateKey, publicKey?: PublicKey) {
|
||||||
this._privateKey = privateKey;
|
this._privateKey = privateKey;
|
||||||
if (!publicKey) {
|
if (!publicKey) {
|
||||||
this._publicKey = PublicKey.fromPrivateKey(this._privateKey);
|
this._publicKey = privateKey.toPublicKey();
|
||||||
} else {
|
} else {
|
||||||
this._publicKey = publicKey;
|
this._publicKey = publicKey;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ export class Keypair {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static generate(): Keypair {
|
public static generate(): Keypair {
|
||||||
return new Keypair(PrivateKey.random());
|
return new Keypair(PrivateKey.fromKeygen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,46 @@
|
||||||
import {SECRET_KEY_LENGTH} from "./constants";
|
import * as blst from "@chainsafe/blst-ts";
|
||||||
import assert from "assert";
|
import {blst as blstBindings} from "@chainsafe/blst-ts/dist/bindings";
|
||||||
import {SecretKeyType} from "@chainsafe/eth2-bls-wasm";
|
import {bytesToHex, getRandomBytes, hexToBytes} from "./helpers/utils";
|
||||||
import {generateRandomSecretKey} from "@chainsafe/bls-keygen";
|
|
||||||
import {getContext} from "./context";
|
|
||||||
import {PublicKey} from "./publicKey";
|
import {PublicKey} from "./publicKey";
|
||||||
import {Signature} from "./signature";
|
import {Signature} from "./signature";
|
||||||
|
|
||||||
export class PrivateKey {
|
export class PrivateKey {
|
||||||
private value: SecretKeyType;
|
readonly value: blst.SecretKey;
|
||||||
|
|
||||||
protected constructor(value: SecretKeyType) {
|
constructor(value: blst.SecretKey) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromBytes(bytes: Uint8Array): PrivateKey {
|
static fromBytes(bytes: Uint8Array): PrivateKey {
|
||||||
assert(bytes.length === SECRET_KEY_LENGTH, "Private key should have 32 bytes");
|
const sk = blst.SecretKey.fromBytes(bytes);
|
||||||
const context = getContext();
|
return new PrivateKey(sk);
|
||||||
const secretKey = new context.SecretKey();
|
|
||||||
secretKey.deserialize(Buffer.from(bytes));
|
|
||||||
return new PrivateKey(secretKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromHexString(value: string): PrivateKey {
|
static fromHex(hex: string): PrivateKey {
|
||||||
value = value.replace("0x", "");
|
return this.fromBytes(hexToBytes(hex));
|
||||||
assert(value.length === SECRET_KEY_LENGTH * 2, "secret key must have 32 bytes");
|
|
||||||
const context = getContext();
|
|
||||||
return new PrivateKey(context.deserializeHexStrToSecretKey(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromInt(num: number): PrivateKey {
|
static fromKeygen(entropy?: Uint8Array): PrivateKey {
|
||||||
const context = getContext();
|
const sk = blst.SecretKey.fromKeygen(entropy || getRandomBytes(32));
|
||||||
const secretKey = new context.SecretKey();
|
return new PrivateKey(sk);
|
||||||
secretKey.setInt(num);
|
|
||||||
return new PrivateKey(secretKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static random(): PrivateKey {
|
signMessage(message: Uint8Array): Signature {
|
||||||
const randomKey: Buffer = generateRandomSecretKey();
|
|
||||||
return this.fromBytes(randomKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getValue(): SecretKeyType {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public sign(message: Uint8Array): Signature {
|
|
||||||
// return Signature.fromValue(this.value.sign(message));
|
|
||||||
// }
|
|
||||||
|
|
||||||
public signMessage(message: Uint8Array): Signature {
|
|
||||||
return Signature.fromValue(this.value.sign(message));
|
return Signature.fromValue(this.value.sign(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public toPublicKey(): PublicKey {
|
toPublicKey(): PublicKey {
|
||||||
return PublicKey.fromPublicKeyType(this.value.getPublicKey());
|
const p1 = new blstBindings.P1(this.value.value);
|
||||||
|
const jacobian = new blst.AggregatePublicKey(p1);
|
||||||
|
const affine = jacobian.toPublicKey();
|
||||||
|
return new PublicKey(affine, jacobian);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toBytes(): Buffer {
|
toBytes(): Buffer {
|
||||||
return Buffer.from(this.value.serialize());
|
return Buffer.from(this.value.toBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public toHexString(): string {
|
toHex(): string {
|
||||||
return `0x${this.value.serializeToHexStr()}`;
|
return bytesToHex(this.toBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +1,47 @@
|
||||||
import {PrivateKey} from "./privateKey";
|
import * as blst from "@chainsafe/blst-ts";
|
||||||
import {PublicKeyType} from "@chainsafe/eth2-bls-wasm";
|
import {blst as blstBindings} from "@chainsafe/blst-ts/dist/bindings";
|
||||||
import {getContext} from "./context";
|
|
||||||
import {PUBLIC_KEY_LENGTH} from "./constants";
|
|
||||||
import assert from "assert";
|
|
||||||
import {Signature} from "./signature";
|
import {Signature} from "./signature";
|
||||||
import {EMPTY_PUBLIC_KEY} from "./helpers/utils";
|
import {bytesToHex, hexToBytes} from "./helpers/utils";
|
||||||
|
|
||||||
export class PublicKey {
|
export class PublicKey {
|
||||||
private value: PublicKeyType;
|
readonly affine: blst.PublicKey;
|
||||||
|
readonly jacobian: blst.AggregatePublicKey;
|
||||||
|
|
||||||
protected constructor(value: PublicKeyType) {
|
constructor(affine: blst.PublicKey, jacobian: blst.AggregatePublicKey) {
|
||||||
this.value = value;
|
this.affine = affine;
|
||||||
|
this.jacobian = jacobian;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromPrivateKey(privateKey: PrivateKey): PublicKey {
|
static fromBytes(bytes: Uint8Array): PublicKey {
|
||||||
return privateKey.toPublicKey();
|
const affine = blst.PublicKey.fromBytes(bytes);
|
||||||
|
const jacobian = blst.AggregatePublicKey.fromPublicKey(affine);
|
||||||
|
return new PublicKey(affine, jacobian);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromBytes(bytes: Uint8Array): PublicKey {
|
static fromHex(hex: string): PublicKey {
|
||||||
const context = getContext();
|
return this.fromBytes(hexToBytes(hex));
|
||||||
const publicKey = new context.PublicKey();
|
|
||||||
if (!EMPTY_PUBLIC_KEY.equals(bytes)) {
|
|
||||||
publicKey.deserialize(bytes);
|
|
||||||
}
|
|
||||||
return new PublicKey(publicKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromHex(value: string): PublicKey {
|
static aggregate(pubkeys: PublicKey[]): PublicKey {
|
||||||
value = value.replace("0x", "");
|
const p1Arr = pubkeys.map((pk) => pk.jacobian.value);
|
||||||
assert(value.length === PUBLIC_KEY_LENGTH * 2);
|
const aggP1 = p1Arr.reduce((_agg, pk) => {
|
||||||
const context = getContext();
|
return blstBindings.P1.add(_agg, pk);
|
||||||
return new PublicKey(context.deserializeHexStrToPublicKey(value));
|
});
|
||||||
|
|
||||||
|
const jacobian = new blst.AggregatePublicKey(aggP1);
|
||||||
|
const affine = jacobian.toPublicKey();
|
||||||
|
return new PublicKey(affine, jacobian);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromPublicKeyType(value: PublicKeyType): PublicKey {
|
verifyMessage(signature: Signature, message: Uint8Array): boolean {
|
||||||
return new PublicKey(value);
|
return blst.verify(message, this.affine, signature.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public add(other: PublicKey): PublicKey {
|
toBytes(): Buffer {
|
||||||
const agg = new PublicKey(this.value.clone());
|
return Buffer.from(this.affine.toBytes());
|
||||||
agg.value.add(other.value);
|
|
||||||
return agg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public verifyMessage(signature: Signature, messageHash: Uint8Array): boolean {
|
toHex(): string {
|
||||||
return this.value.verify(signature.getValue(), messageHash);
|
return bytesToHex(this.toBytes());
|
||||||
}
|
|
||||||
|
|
||||||
public toBytesCompressed(): Buffer {
|
|
||||||
return Buffer.from(this.value.serialize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public toHexString(): string {
|
|
||||||
return `0x${this.toBytesCompressed().toString("hex")}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getValue(): PublicKeyType {
|
|
||||||
return this.value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +1,53 @@
|
||||||
import assert from "assert";
|
import * as blst from "@chainsafe/blst-ts";
|
||||||
import {FP_POINT_LENGTH} from "./constants";
|
import {blst as blstBindings} from "@chainsafe/blst-ts/dist/bindings";
|
||||||
import {SignatureType} from "@chainsafe/eth2-bls-wasm";
|
import {bytesToHex, hexToBytes} from "./helpers/utils";
|
||||||
import {getContext} from "./context";
|
|
||||||
import {PublicKey} from "./publicKey";
|
import {PublicKey} from "./publicKey";
|
||||||
import {EMPTY_SIGNATURE} from "./helpers/utils";
|
|
||||||
|
|
||||||
export class Signature {
|
export class Signature {
|
||||||
private value: SignatureType;
|
readonly value: blst.Signature;
|
||||||
|
|
||||||
protected constructor(value: SignatureType) {
|
constructor(value: blst.Signature) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
assert(this.value.isValidOrder());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromCompressedBytes(value: Uint8Array): Signature {
|
static fromBytes(bytes: Uint8Array): Signature {
|
||||||
assert(value.length === 2 * FP_POINT_LENGTH, `Signature must have ${2 * FP_POINT_LENGTH} bytes`);
|
return new Signature(blst.Signature.fromBytes(bytes));
|
||||||
const context = getContext();
|
|
||||||
const signature = new context.Signature();
|
|
||||||
if (!EMPTY_SIGNATURE.equals(value)) {
|
|
||||||
signature.deserialize(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromHex(hex: string): Signature {
|
||||||
|
return this.fromBytes(hexToBytes(hex));
|
||||||
|
}
|
||||||
|
|
||||||
|
static fromValue(signature: blst.Signature): Signature {
|
||||||
return new Signature(signature);
|
return new Signature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromValue(signature: SignatureType): Signature {
|
static aggregate(signatures: Signature[]): Signature {
|
||||||
return new Signature(signature);
|
const agg = blst.AggregateSignature.fromSignatures(signatures.map((sig) => sig.value));
|
||||||
|
return new Signature(agg.toSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static aggregate(signatures: Signature[]): Signature {
|
verifyAggregate(publicKeys: PublicKey[], message: Uint8Array): boolean {
|
||||||
const context = getContext();
|
return blst.fastAggregateVerify(
|
||||||
const signature = new context.Signature();
|
message,
|
||||||
signature.aggregate(signatures.map((sig) => sig.getValue()));
|
publicKeys.map((pk) => pk.affine),
|
||||||
return new Signature(signature);
|
this.value
|
||||||
}
|
|
||||||
|
|
||||||
public add(other: Signature): Signature {
|
|
||||||
const agg = this.value.clone();
|
|
||||||
agg.add(other.value);
|
|
||||||
return new Signature(agg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getValue(): SignatureType {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[]): boolean {
|
||||||
const msgs = Buffer.concat(messages);
|
return blst.aggregateVerify(
|
||||||
if (!fast && !getContext().areAllMsgDifferent(msgs)) {
|
messages,
|
||||||
return false;
|
publicKeys.map((pk) => pk.affine),
|
||||||
}
|
this.value
|
||||||
return this.value.aggregateVerifyNoCheck(
|
|
||||||
publicKeys.map((key) => key.getValue()),
|
|
||||||
msgs
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public toBytesCompressed(): Buffer {
|
toBytes(): Buffer {
|
||||||
return Buffer.from(this.value.serialize());
|
return Buffer.from(this.value.toBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public toHex(): string {
|
toHex(): string {
|
||||||
return "0x" + this.value.serializeToHexStr();
|
return bytesToHex(this.toBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ import {runBenchmark} from "./runner";
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
testRunner: (pks) => {
|
testRunner: (pks) => {
|
||||||
pks.reduce((agg, pk) => agg.add(pk));
|
herumi.PublicKey.aggregate(pks);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe("test bls", function () {
|
||||||
const keypair = Keypair.generate();
|
const keypair = Keypair.generate();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
|
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());
|
const result = verify(keypair.publicKey.toBytes(), messageHash, signature.toBytes());
|
||||||
expect(result).to.be.true;
|
expect(result).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -31,16 +31,16 @@ describe("test bls", function () {
|
||||||
const keypair = Keypair.generate();
|
const keypair = Keypair.generate();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
|
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();
|
const pubKey = keypair.publicKey.toBytes();
|
||||||
verify(pubKey, messageHash, signature.toBytesCompressed());
|
verify(pubKey, messageHash, signature.toBytes());
|
||||||
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHexString());
|
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHex());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail verify empty signature", () => {
|
it("should fail verify empty signature", () => {
|
||||||
const keypair = Keypair.generate();
|
const 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 signature = Buffer.alloc(96);
|
||||||
const result = verify(keypair.publicKey.toBytesCompressed(), messageHash2, signature);
|
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature);
|
||||||
expect(result).to.be.false;
|
expect(result).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ describe("test bls", function () {
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
||||||
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
|
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2")));
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
const signature = keypair.privateKey.signMessage(messageHash);
|
||||||
const result = verify(keypair.publicKey.toBytesCompressed(), messageHash2, signature.toBytesCompressed());
|
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature.toBytes());
|
||||||
expect(result).to.be.false;
|
expect(result).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ describe("test bls", function () {
|
||||||
const keypair2 = Keypair.generate();
|
const keypair2 = Keypair.generate();
|
||||||
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
|
||||||
const signature = keypair.privateKey.signMessage(messageHash);
|
const signature = keypair.privateKey.signMessage(messageHash);
|
||||||
const result = verify(keypair2.publicKey.toBytesCompressed(), messageHash, signature.toBytesCompressed());
|
const result = verify(keypair2.publicKey.toBytes(), messageHash, signature.toBytes());
|
||||||
expect(result).to.be.false;
|
expect(result).to.be.false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -80,21 +80,15 @@ describe("test bls", function () {
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
const signature3 = keypair3.privateKey.signMessage(message2);
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
const signature4 = keypair4.privateKey.signMessage(message2);
|
||||||
|
|
||||||
const aggregatePubKey12 = aggregatePubkeys([
|
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
||||||
keypair1.publicKey.toBytesCompressed(),
|
|
||||||
keypair2.publicKey.toBytesCompressed(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const aggregatePubKey34 = aggregatePubkeys([
|
const aggregatePubKey34 = aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
|
||||||
keypair3.publicKey.toBytesCompressed(),
|
|
||||||
keypair4.publicKey.toBytesCompressed(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
const aggregateSignature = aggregateSignatures([
|
||||||
signature1.toBytesCompressed(),
|
signature1.toBytes(),
|
||||||
signature2.toBytesCompressed(),
|
signature2.toBytes(),
|
||||||
signature3.toBytesCompressed(),
|
signature3.toBytes(),
|
||||||
signature4.toBytesCompressed(),
|
signature4.toBytes(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message1, message2], aggregateSignature);
|
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message1, message2], aggregateSignature);
|
||||||
|
@ -118,22 +112,21 @@ describe("test bls", function () {
|
||||||
const signature4 = keypair4.privateKey.signMessage(message);
|
const signature4 = keypair4.privateKey.signMessage(message);
|
||||||
|
|
||||||
const aggregateSignature = aggregateSignatures([
|
const aggregateSignature = aggregateSignatures([
|
||||||
signature1.toBytesCompressed(),
|
signature1.toBytes(),
|
||||||
signature2.toBytesCompressed(),
|
signature2.toBytes(),
|
||||||
signature3.toBytesCompressed(),
|
signature3.toBytes(),
|
||||||
signature4.toBytesCompressed(),
|
signature4.toBytes(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = verifyMultiple(
|
const result = verifyMultiple(
|
||||||
[
|
[
|
||||||
keypair1.publicKey.toBytesCompressed(),
|
keypair1.publicKey.toBytes(),
|
||||||
keypair2.publicKey.toBytesCompressed(),
|
keypair2.publicKey.toBytes(),
|
||||||
keypair3.publicKey.toBytesCompressed(),
|
keypair3.publicKey.toBytes(),
|
||||||
keypair4.publicKey.toBytesCompressed(),
|
keypair4.publicKey.toBytes(),
|
||||||
],
|
],
|
||||||
[message, message, message, message],
|
[message, message, message, message],
|
||||||
aggregateSignature,
|
aggregateSignature
|
||||||
true
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(result).to.be.true;
|
expect(result).to.be.true;
|
||||||
|
@ -155,21 +148,15 @@ describe("test bls", function () {
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
const signature3 = keypair3.privateKey.signMessage(message2);
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
const signature4 = keypair4.privateKey.signMessage(message2);
|
||||||
|
|
||||||
const aggregatePubKey12 = bls.aggregatePubkeys([
|
const aggregatePubKey12 = bls.aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
||||||
keypair1.publicKey.toBytesCompressed(),
|
|
||||||
keypair2.publicKey.toBytesCompressed(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const aggregatePubKey34 = bls.aggregatePubkeys([
|
const aggregatePubKey34 = bls.aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
|
||||||
keypair3.publicKey.toBytesCompressed(),
|
|
||||||
keypair4.publicKey.toBytesCompressed(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const aggregateSignature = bls.aggregateSignatures([
|
const aggregateSignature = bls.aggregateSignatures([
|
||||||
signature1.toBytesCompressed(),
|
signature1.toBytes(),
|
||||||
signature2.toBytesCompressed(),
|
signature2.toBytes(),
|
||||||
signature3.toBytesCompressed(),
|
signature3.toBytes(),
|
||||||
signature4.toBytesCompressed(),
|
signature4.toBytes(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = bls.verifyMultiple(
|
const result = bls.verifyMultiple(
|
||||||
|
@ -195,16 +182,13 @@ describe("test bls", function () {
|
||||||
const signature3 = keypair3.privateKey.signMessage(message2);
|
const signature3 = keypair3.privateKey.signMessage(message2);
|
||||||
const signature4 = keypair4.privateKey.signMessage(message2);
|
const signature4 = keypair4.privateKey.signMessage(message2);
|
||||||
|
|
||||||
const aggregatePubKey12 = bls.aggregatePubkeys([
|
const aggregatePubKey12 = bls.aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
|
||||||
keypair1.publicKey.toBytesCompressed(),
|
|
||||||
keypair2.publicKey.toBytesCompressed(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const aggregateSignature = bls.aggregateSignatures([
|
const aggregateSignature = bls.aggregateSignatures([
|
||||||
signature1.toBytesCompressed(),
|
signature1.toBytes(),
|
||||||
signature2.toBytesCompressed(),
|
signature2.toBytes(),
|
||||||
signature3.toBytesCompressed(),
|
signature3.toBytes(),
|
||||||
signature4.toBytesCompressed(),
|
signature4.toBytes(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const result = bls.verifyMultiple([aggregatePubKey12], [message2, message1], aggregateSignature);
|
const result = bls.verifyMultiple([aggregatePubKey12], [message2, message1], aggregateSignature);
|
||||||
|
|
|
@ -12,9 +12,9 @@ describe("keypair", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create from private and public key", () => {
|
it("should create from private and public key", () => {
|
||||||
const secret = PrivateKey.random();
|
const secret = PrivateKey.fromKeygen();
|
||||||
const secret2 = PrivateKey.random();
|
const secret2 = PrivateKey.fromKeygen();
|
||||||
const publicKey = PublicKey.fromBytes(PublicKey.fromPrivateKey(secret2).toBytesCompressed());
|
const publicKey = PublicKey.fromBytes(secret2.toPublicKey().toBytes());
|
||||||
const keypair = new Keypair(secret, publicKey);
|
const keypair = new Keypair(secret, publicKey);
|
||||||
expect(keypair.publicKey).to.be.equal(publicKey);
|
expect(keypair.publicKey).to.be.equal(publicKey);
|
||||||
expect(keypair.privateKey).to.be.equal(secret);
|
expect(keypair.privateKey).to.be.equal(secret);
|
||||||
|
@ -22,11 +22,9 @@ describe("keypair", function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create from private", () => {
|
it("should create from private", () => {
|
||||||
const secret = PrivateKey.random();
|
const secret = PrivateKey.fromKeygen();
|
||||||
const publicKey = PublicKey.fromPrivateKey(secret);
|
const publicKey = secret.toPublicKey();
|
||||||
const keypair = new Keypair(secret);
|
const keypair = new Keypair(secret);
|
||||||
expect(keypair.publicKey.toBytesCompressed().toString("hex")).to.be.equal(
|
expect(keypair.publicKey.toBytes().toString("hex")).to.be.equal(publicKey.toBytes().toString("hex"));
|
||||||
publicKey.toBytesCompressed().toString("hex")
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,27 +12,27 @@ describe("privateKey", function () {
|
||||||
destroy();
|
destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should generate random private key", function () {
|
it("should generate fromKeygen private key", function () {
|
||||||
const privateKey1 = PrivateKey.random();
|
const privateKey1 = PrivateKey.fromKeygen();
|
||||||
const privateKey2 = PrivateKey.random();
|
const privateKey2 = PrivateKey.fromKeygen();
|
||||||
expect(privateKey1.toHexString()).to.not.be.equal(privateKey2.toHexString());
|
expect(privateKey1.toHex()).to.not.be.equal(privateKey2.toHex());
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should export private key to hex string", function () {
|
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.fromHex(privateKey).toHex()).to.be.equal(privateKey);
|
||||||
|
|
||||||
const privateKey2 = "07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
|
const privateKey2 = "07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
|
||||||
|
|
||||||
expect(PrivateKey.fromHexString(privateKey2).toHexString()).to.be.equal(privateKey);
|
expect(PrivateKey.fromHex(privateKey2).toHex()).to.be.equal(privateKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should export private key to bytes", function () {
|
it("should export private key to bytes", function () {
|
||||||
expect(PrivateKey.random().toBytes().length).to.be.equal(SECRET_KEY_LENGTH);
|
expect(PrivateKey.fromKeygen().toBytes().length).to.be.equal(SECRET_KEY_LENGTH);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not accept too short private key", function () {
|
it("should not accept too short private key", function () {
|
||||||
expect(() => PrivateKey.fromHexString("0x2123")).to.throw();
|
expect(() => PrivateKey.fromHex("0x2123")).to.throw();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,16 +14,16 @@ describe("public key", function () {
|
||||||
it("from hex", function () {
|
it("from hex", function () {
|
||||||
const publicKey =
|
const publicKey =
|
||||||
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
||||||
expect(PublicKey.fromHex(publicKey).toHexString()).to.be.equal(publicKey);
|
expect(PublicKey.fromHex(publicKey).toHex()).to.be.equal(publicKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("from bytes", function () {
|
it("from bytes", function () {
|
||||||
const publicKey =
|
const publicKey =
|
||||||
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
|
||||||
expect(PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHexString()).to.be.equal(`0x${publicKey}`);
|
expect(PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHex()).to.be.equal(`0x${publicKey}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("from private key", function () {
|
it("from private key", function () {
|
||||||
PublicKey.fromPrivateKey(PrivateKey.random());
|
PrivateKey.fromKeygen().toPublicKey();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -821,7 +821,9 @@
|
||||||
buffer "^5.4.3"
|
buffer "^5.4.3"
|
||||||
|
|
||||||
"@chainsafe/blst-ts@file:../blst-ts":
|
"@chainsafe/blst-ts@file:../blst-ts":
|
||||||
version "1.0.0"
|
version "0.1.1"
|
||||||
|
dependencies:
|
||||||
|
node-fetch "^2.6.1"
|
||||||
|
|
||||||
"@chainsafe/eth2-bls-wasm@^0.5.0":
|
"@chainsafe/eth2-bls-wasm@^0.5.0":
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
|
@ -4415,6 +4417,11 @@ node-environment-flags@1.0.5:
|
||||||
object.getownpropertydescriptors "^2.0.3"
|
object.getownpropertydescriptors "^2.0.3"
|
||||||
semver "^5.7.0"
|
semver "^5.7.0"
|
||||||
|
|
||||||
|
node-fetch@^2.6.1:
|
||||||
|
version "2.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||||
|
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||||
|
|
||||||
node-libs-browser@^2.2.1:
|
node-libs-browser@^2.2.1:
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
||||||
|
|
Reference in New Issue