Merge pull request #1 from ChainSafe/spec-0.10.1

Align with spec 0.10.1
This commit is contained in:
Marin Petrunić 2020-02-25 09:18:07 +01:00 committed by GitHub
commit 789104878d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 150 deletions

View File

@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/ChainSafe/lodestar.svg?branch=master)](https://travis-ci.org/ChainSafe/lodestar) [![Build Status](https://travis-ci.org/ChainSafe/lodestar.svg?branch=master)](https://travis-ci.org/ChainSafe/lodestar)
[![codecov](https://codecov.io/gh/ChainSafe/lodestar/branch/master/graph/badge.svg)](https://codecov.io/gh/ChainSafe/lodestar) [![codecov](https://codecov.io/gh/ChainSafe/lodestar/branch/master/graph/badge.svg)](https://codecov.io/gh/ChainSafe/lodestar)
![ETH2.0_Spec_Version 0.9.4](https://img.shields.io/badge/ETH2.0_Spec_Version-0.9.4-2e86c1.svg) ![ETH2.0_Spec_Version 0.10.1](https://img.shields.io/badge/ETH2.0_Spec_Version-0.10.1-2e86c1.svg)
This is a Javascript library that implements BLS (Boneh-Lynn-Shacham) signatures and supports signature aggregation. This is a Javascript library that implements BLS (Boneh-Lynn-Shacham) signatures and supports signature aggregation.

View File

@ -39,7 +39,7 @@
}, },
"dependencies": { "dependencies": {
"@chainsafe/bls-keygen": "^0.0.2", "@chainsafe/bls-keygen": "^0.0.2",
"@chainsafe/eth2-bls-wasm": "^0.2.1", "@chainsafe/eth2-bls-wasm": "^0.4.0",
"assert": "^1.4.1" "assert": "^1.4.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -34,17 +34,12 @@ export function generatePublicKey(secretKey: Uint8Array): Buffer {
* Signs given message using secret key. * Signs given message using secret key.
* @param secretKey * @param secretKey
* @param messageHash * @param messageHash
* @param domain
*/ */
export function sign(secretKey: Uint8Array, messageHash: Uint8Array, domain: Uint8Array): Buffer { 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");
assert(domain, "domain is null or undefined");
const privateKey = PrivateKey.fromBytes(toBuffer(secretKey)); const privateKey = PrivateKey.fromBytes(toBuffer(secretKey));
return privateKey.signMessage( return privateKey.signMessage(toBuffer(messageHash)).toBytesCompressed();
toBuffer(messageHash),
toBuffer(domain),
).toBytesCompressed();
} }
/** /**
@ -53,11 +48,11 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array, domain: Uin
*/ */
export function aggregateSignatures(signatures: Uint8Array[]): Buffer { export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
assert(signatures, "signatures is null or undefined"); assert(signatures, "signatures is null or undefined");
return signatures.map((signature): Signature => { return Signature.aggregate(
return Signature.fromCompressedBytes(toBuffer(signature)); signatures.map((signature): Signature => {
}).reduce((previousValue, currentValue): Signature => { return Signature.fromCompressedBytes(signature);
return previousValue.add(currentValue); })
}).toBytesCompressed(); ).toBytesCompressed();
} }
/** /**
@ -80,26 +75,34 @@ export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
* @param publicKey * @param publicKey
* @param messageHash * @param messageHash
* @param signature * @param signature
* @param domain
*/ */
export function verify( export function verify(publicKey: Uint8Array, messageHash: Uint8Array, signature: Uint8Array): boolean {
publicKey: Uint8Array,
messageHash: Uint8Array,
signature: Uint8Array,
domain: Uint8Array
): boolean {
assert(publicKey, "publicKey is null or undefined"); assert(publicKey, "publicKey is null or undefined");
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");
assert(domain, "domain is null or undefined");
try { try {
return PublicKey return PublicKey
.fromBytes(toBuffer(publicKey)) .fromBytes(publicKey)
.verifyMessage( .verifyMessage(Signature.fromCompressedBytes(toBuffer(signature)), toBuffer(messageHash));
Signature.fromCompressedBytes(toBuffer(signature)), } catch (e) {
toBuffer(messageHash), return false;
toBuffer(domain) }
); }
/**
* Verifies if aggregated signature is same message signed with given public keys.
* @param publicKeys
* @param messageHash
* @param signature
*/
export function verifyAggregate(publicKeys: Uint8Array[], messageHash: Uint8Array, signature: Uint8Array): boolean {
assert(publicKeys, "publicKey is null or undefined");
assert(messageHash, "messageHash is null or undefined");
assert(signature, "signature is null or undefined");
try {
return Signature
.fromCompressedBytes(signature)
.verifyAggregate(publicKeys, messageHash);
} catch (e) { } catch (e) {
return false; return false;
} }
@ -110,18 +113,17 @@ export function verify(
* @param publicKeys * @param publicKeys
* @param messageHashes * @param messageHashes
* @param signature * @param signature
* @param domain * @param fast Check if all messages are different
*/ */
export function verifyMultiple( export function verifyMultiple(
publicKeys: Uint8Array[], publicKeys: Uint8Array[],
messageHashes: Uint8Array[], messageHashes: Uint8Array[],
signature: Uint8Array, signature: Uint8Array,
domain: Uint8Array fast = false
): boolean { ): 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");
assert(domain, "domain is null or undefined");
if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) { if(publicKeys.length === 0 || publicKeys.length != messageHashes.length) {
return false; return false;
@ -132,7 +134,7 @@ export function verifyMultiple(
.verifyMultiple( .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)),
toBuffer(domain), fast
); );
} catch (e) { } catch (e) {
return false; return false;
@ -146,5 +148,6 @@ export default {
aggregateSignatures, aggregateSignatures,
aggregatePubkeys, aggregatePubkeys,
verify, verify,
verifyAggregate,
verifyMultiple verifyMultiple
}; };

View File

@ -5,7 +5,6 @@ import {generateRandomSecretKey} from "@chainsafe/bls-keygen";
import {getContext} from "./context"; import {getContext} from "./context";
import {PublicKey} from "./publicKey"; import {PublicKey} from "./publicKey";
import {Signature} from "./signature"; import {Signature} from "./signature";
import {padLeft} from "./helpers/utils";
export class PrivateKey { export class PrivateKey {
@ -50,9 +49,8 @@ export class PrivateKey {
// return Signature.fromValue(this.value.sign(message)); // return Signature.fromValue(this.value.sign(message));
// } // }
public signMessage(message: Uint8Array, domain: Uint8Array): Signature { public signMessage(message: Uint8Array): Signature {
domain = padLeft(domain, 8); return Signature.fromValue(this.value.sign(message));
return Signature.fromValue(this.value.signHashWithDomain(Buffer.concat([message, domain])));
} }
public toPublicKey(): PublicKey { public toPublicKey(): PublicKey {

View File

@ -48,8 +48,8 @@ export class PublicKey {
return agg; return agg;
} }
public verifyMessage(signature: Signature, messageHash: Uint8Array, domain: Uint8Array): boolean { public verifyMessage(signature: Signature, messageHash: Uint8Array): boolean {
return this.value.verifyHashWithDomain(signature.getValue(), Buffer.concat([messageHash, domain])); return this.value.verify(signature.getValue(), messageHash);
} }
public toBytesCompressed(): Buffer { public toBytesCompressed(): Buffer {

View File

@ -3,7 +3,7 @@ import {FP_POINT_LENGTH} from "./constants";
import {SignatureType} from "@chainsafe/eth2-bls-wasm"; import {SignatureType} from "@chainsafe/eth2-bls-wasm";
import {getContext} from "./context"; import {getContext} from "./context";
import {PublicKey} from "./publicKey"; import {PublicKey} from "./publicKey";
import {EMPTY_SIGNATURE, padLeft} from "./helpers/utils"; import {EMPTY_SIGNATURE} from "./helpers/utils";
export class Signature { export class Signature {
@ -11,6 +11,7 @@ export class Signature {
protected constructor(value: SignatureType) { protected constructor(value: SignatureType) {
this.value = value; this.value = value;
assert(this.value.isValidOrder());
} }
public static fromCompressedBytes(value: Uint8Array): Signature { public static fromCompressedBytes(value: Uint8Array): Signature {
@ -30,6 +31,15 @@ export class Signature {
return new Signature(signature); return new Signature(signature);
} }
public static aggregate(signatures: Signature[]): Signature {
const context = getContext();
const signature = new context.Signature();
signature.aggregate(signatures.map((sig) => sig.getValue()));
return new Signature(
signature
);
}
public add(other: Signature): Signature { public add(other: Signature): Signature {
const agg = this.value.clone(); const agg = this.value.clone();
agg.add(other.value); agg.add(other.value);
@ -42,16 +52,21 @@ export class Signature {
return this.value; return this.value;
} }
public verify(publicKey: PublicKey, message: Uint8Array, domain: Uint8Array): boolean { public verifyAggregate(publicKey: Uint8Array[], message: Uint8Array): boolean {
domain = padLeft(domain, 8); return this.value.fastAggregateVerify(
return publicKey.verifyMessage(this, message, domain); publicKey.map((bytes) => PublicKey.fromBytes(bytes).getValue()),
message
);
} }
public verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[], domain: Uint8Array): boolean { public verifyMultiple(publicKeys: PublicKey[], messages: Uint8Array[], fast = false): boolean {
domain = padLeft(domain, 8); const msgs = Buffer.concat(messages);
return this.value.verifyAggregatedHashWithDomain( if(!fast && !getContext().areAllMsgDifferent(msgs)) {
return false;
}
return this.value.aggregateVerifyNoCheck(
publicKeys.map((key) => key.getValue()), publicKeys.map((key) => key.getValue()),
messages.map((message) => Buffer.concat([message, domain])) msgs
); );
} }

View File

@ -24,16 +24,13 @@ describe("test bls", function () {
it("should verify signature", () => { it("should verify signature", () => {
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 domain = Buffer.alloc(8, 1);
const signature = keypair.privateKey.signMessage( const signature = keypair.privateKey.signMessage(
messageHash, messageHash,
domain
); );
const result = verify( const result = verify(
keypair.publicKey.toBytesCompressed(), keypair.publicKey.toBytesCompressed(),
messageHash, messageHash,
signature.toBytesCompressed(), signature.toBytesCompressed(),
domain
); );
expect(result).to.be.true; expect(result).to.be.true;
}); });
@ -42,17 +39,14 @@ describe("test bls", function () {
it("should not modify original pubkey when verifying", () => { it("should not modify original pubkey when verifying", () => {
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 domain = Buffer.alloc(8, 1);
const signature = keypair.privateKey.signMessage( const signature = keypair.privateKey.signMessage(
messageHash, messageHash,
domain
); );
const pubKey = keypair.publicKey.toBytesCompressed(); const pubKey = keypair.publicKey.toBytesCompressed();
verify( verify(
pubKey, pubKey,
messageHash, messageHash,
signature.toBytesCompressed(), signature.toBytesCompressed(),
domain
); );
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHexString()); expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHexString());
}); });
@ -61,13 +55,11 @@ describe("test bls", function () {
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 domain = Buffer.from("01", "hex");
const signature = Buffer.alloc(96); const signature = Buffer.alloc(96);
const result = verify( const result = verify(
keypair.publicKey.toBytesCompressed(), keypair.publicKey.toBytesCompressed(),
messageHash2, messageHash2,
signature, signature,
domain
); );
expect(result).to.be.false; expect(result).to.be.false;
}); });
@ -76,34 +68,13 @@ describe("test bls", function () {
const keypair = Keypair.generate(); const keypair = Keypair.generate();
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 domain = padLeft(Buffer.from("01", "hex"), 8);
const signature = keypair.privateKey.signMessage( const signature = keypair.privateKey.signMessage(
messageHash, messageHash,
domain
); );
const result = verify( const result = verify(
keypair.publicKey.toBytesCompressed(), keypair.publicKey.toBytesCompressed(),
messageHash2, messageHash2,
signature.toBytesCompressed(), signature.toBytesCompressed(),
domain
);
expect(result).to.be.false;
});
it("should fail verify signature of different domain", () => {
const keypair = Keypair.generate();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message")));
const domain = padLeft(Buffer.from("01", "hex"), 8);
const domain2 = padLeft(Buffer.from("02", "hex"), 8);
const signature = keypair.privateKey.signMessage(
messageHash,
domain
);
const result = verify(
keypair.publicKey.toBytesCompressed(),
messageHash,
signature.toBytesCompressed(),
domain2
); );
expect(result).to.be.false; expect(result).to.be.false;
}); });
@ -112,16 +83,13 @@ describe("test bls", function () {
const keypair = Keypair.generate(); const keypair = Keypair.generate();
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 domain = Buffer.from("01", "hex");
const signature = keypair.privateKey.signMessage( const signature = keypair.privateKey.signMessage(
messageHash, messageHash,
domain
); );
const result = verify( const result = verify(
keypair2.publicKey.toBytesCompressed(), keypair2.publicKey.toBytesCompressed(),
messageHash, messageHash,
signature.toBytesCompressed(), signature.toBytesCompressed(),
domain
); );
expect(result).to.be.false; expect(result).to.be.false;
}); });
@ -133,7 +101,6 @@ describe("test bls", function () {
this.timeout(5000); this.timeout(5000);
const domain = Buffer.alloc(8, 0);
const keypair1 = Keypair.generate(); const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate(); const keypair2 = Keypair.generate();
@ -143,10 +110,10 @@ describe("test bls", function () {
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2"))); const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1, domain); const signature1 = keypair1.privateKey.signMessage(message1);
const signature2 = keypair2.privateKey.signMessage(message1, domain); const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2, domain); const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2, domain); const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = aggregatePubkeys([ const aggregatePubKey12 = aggregatePubkeys([
keypair1.publicKey.toBytesCompressed(), keypair1.publicKey.toBytesCompressed(),
@ -169,7 +136,6 @@ describe("test bls", function () {
[aggregatePubKey12, aggregatePubKey34], [aggregatePubKey12, aggregatePubKey34],
[message1, message2], [message1, message2],
aggregateSignature, aggregateSignature,
domain
); );
expect(result).to.be.true; expect(result).to.be.true;
@ -179,7 +145,6 @@ describe("test bls", function () {
this.timeout(5000); this.timeout(5000);
const domain = Buffer.alloc(8, 0);
const keypair1 = Keypair.generate(); const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate(); const keypair2 = Keypair.generate();
@ -188,10 +153,10 @@ describe("test bls", function () {
const message = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const message = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const signature1 = keypair1.privateKey.signMessage(message, domain); const signature1 = keypair1.privateKey.signMessage(message);
const signature2 = keypair2.privateKey.signMessage(message, domain); const signature2 = keypair2.privateKey.signMessage(message);
const signature3 = keypair3.privateKey.signMessage(message, domain); const signature3 = keypair3.privateKey.signMessage(message);
const signature4 = keypair4.privateKey.signMessage(message, domain); const signature4 = keypair4.privateKey.signMessage(message);
const aggregateSignature = aggregateSignatures([ const aggregateSignature = aggregateSignatures([
signature1.toBytesCompressed(), signature1.toBytesCompressed(),
@ -209,7 +174,7 @@ describe("test bls", function () {
], ],
[message, message, message, message], [message, message, message, message],
aggregateSignature, aggregateSignature,
domain true,
); );
expect(result).to.be.true; expect(result).to.be.true;
@ -218,7 +183,6 @@ describe("test bls", function () {
it("should fail to verify aggregated signatures - swapped messages", function () { it("should fail to verify aggregated signatures - swapped messages", function () {
this.timeout(5000); this.timeout(5000);
const domain = Buffer.alloc(8, 0);
const keypair1 = Keypair.generate(); const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate(); const keypair2 = Keypair.generate();
@ -228,10 +192,10 @@ describe("test bls", function () {
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2"))); const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1, domain); const signature1 = keypair1.privateKey.signMessage(message1);
const signature2 = keypair2.privateKey.signMessage(message1, domain); const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2, domain); const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2, domain); const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = bls.aggregatePubkeys([ const aggregatePubKey12 = bls.aggregatePubkeys([
keypair1.publicKey.toBytesCompressed(), keypair1.publicKey.toBytesCompressed(),
@ -254,7 +218,6 @@ describe("test bls", function () {
[aggregatePubKey12, aggregatePubKey34], [aggregatePubKey12, aggregatePubKey34],
[message2, message1], [message2, message1],
aggregateSignature, aggregateSignature,
domain
); );
expect(result).to.be.false; expect(result).to.be.false;
@ -262,7 +225,6 @@ describe("test bls", function () {
it("should fail to verify aggregated signatures - different pubkeys and messsages", () => { it("should fail to verify aggregated signatures - different pubkeys and messsages", () => {
const domain = Buffer.alloc(8, 0);
const keypair1 = Keypair.generate(); const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate(); const keypair2 = Keypair.generate();
@ -272,10 +234,10 @@ describe("test bls", function () {
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2"))); const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1, domain); const signature1 = keypair1.privateKey.signMessage(message1);
const signature2 = keypair2.privateKey.signMessage(message1, domain); const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2, domain); const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2, domain); const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = bls.aggregatePubkeys([ const aggregatePubKey12 = bls.aggregatePubkeys([
keypair1.publicKey.toBytesCompressed(), keypair1.publicKey.toBytesCompressed(),
@ -294,57 +256,13 @@ describe("test bls", function () {
[aggregatePubKey12], [aggregatePubKey12],
[message2, message1], [message2, message1],
aggregateSignature, aggregateSignature,
domain
); );
expect(result).to.be.false; expect(result).to.be.false;
}); });
it("should fail to verify aggregated signatures - different domain", () => {
const domain = Buffer.alloc(8, 0);
const domain2 = Buffer.alloc(8, 1);
const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
const keypair4 = Keypair.generate();
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1, domain);
const signature2 = keypair2.privateKey.signMessage(message1, domain);
const signature3 = keypair3.privateKey.signMessage(message2, domain2);
const signature4 = keypair4.privateKey.signMessage(message2, domain2);
const aggregatePubKey12 = bls.aggregatePubkeys([
keypair1.publicKey.toBytesCompressed(),
keypair2.publicKey.toBytesCompressed(),
]);
const aggregateSignature = bls.aggregateSignatures([
signature1.toBytesCompressed(),
signature2.toBytesCompressed(),
signature3.toBytesCompressed(),
signature4.toBytesCompressed(),
]);
const result = bls.verifyMultiple(
[aggregatePubKey12],
[message2, message1],
aggregateSignature,
domain
);
expect(result).to.be.false;
});
it("should fail to verify aggregated signatures - no public keys", () => { it("should fail to verify aggregated signatures - no public keys", () => {
const domain = Buffer.alloc(8, 0);
const signature = Buffer.alloc(96); const signature = Buffer.alloc(96);
@ -355,7 +273,6 @@ describe("test bls", function () {
[], [],
[message2, message1], [message2, message1],
signature, signature,
domain
); );
expect(result).to.be.false; expect(result).to.be.false;

View File

@ -820,10 +820,10 @@
bip39 "^3.0.2" bip39 "^3.0.2"
buffer "^5.4.3" buffer "^5.4.3"
"@chainsafe/eth2-bls-wasm@^0.2.1": "@chainsafe/eth2-bls-wasm@^0.4.0":
version "0.2.1" version "0.4.0"
resolved "https://registry.yarnpkg.com/@chainsafe/eth2-bls-wasm/-/eth2-bls-wasm-0.2.1.tgz#82710c4b81676eb8a2940394efffc0e59216e731" resolved "https://registry.yarnpkg.com/@chainsafe/eth2-bls-wasm/-/eth2-bls-wasm-0.4.0.tgz#94e89e4e53ec6cdcc07178dbfeb0b80215550d2f"
integrity sha512-optSPu5Ez8tT0iEeCsLhjhMJYyXAZRyPFT2k4q+WrQxr82or5+IVQx4jHdy/uQwMvGB0rlvFYlwsyBrkioTCVw== integrity sha512-4BGktOKmUyyYJNCio5Zn1LdxaGWLhPqdUoZXokrfCLW3SKhw4E6MlnpAHwPtvnDuGSkmdF/GLhYeyjQYTtovqg==
dependencies: dependencies:
buffer "^5.4.3" buffer "^5.4.3"