Update tests to run both implementations

This commit is contained in:
dapplion 2020-11-19 14:41:45 +00:00
parent 57694c2e54
commit f8cd6e7afa
16 changed files with 141 additions and 277 deletions

View File

@ -53,7 +53,6 @@
"@babel/preset-env": "^7.8.4", "@babel/preset-env": "^7.8.4",
"@babel/preset-typescript": "^7.8.3", "@babel/preset-typescript": "^7.8.3",
"@babel/register": "^7.8.3", "@babel/register": "^7.8.3",
"@chainsafe/as-sha256": "0.2.0",
"@chainsafe/eth2-spec-tests": "0.12.0", "@chainsafe/eth2-spec-tests": "0.12.0",
"@chainsafe/lodestar-spec-test-util": "^0.5.0", "@chainsafe/lodestar-spec-test-util": "^0.5.0",
"@types/chai": "^4.2.9", "@types/chai": "^4.2.9",

View File

@ -43,7 +43,7 @@ export function sign(secretKey: Uint8Array, messageHash: Uint8Array): Buffer {
* @param signatures * @param signatures
*/ */
export function aggregateSignatures(signatures: Uint8Array[]): Buffer { export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
assert(signatures && signatures.length > 0, "EMPTY_AGGREGATE_ARRAY"); assert(signatures, "signatures is null or undefined");
const agg = Signature.aggregate(signatures.map((signature): Signature => Signature.fromBytes(signature))); const agg = Signature.aggregate(signatures.map((signature): Signature => Signature.fromBytes(signature)));
return agg.toBytes(); return agg.toBytes();
} }
@ -54,13 +54,8 @@ export function aggregateSignatures(signatures: Uint8Array[]): Buffer {
*/ */
export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer { export function aggregatePubkeys(publicKeys: Uint8Array[]): Buffer {
assert(publicKeys, "publicKeys is null or undefined"); assert(publicKeys, "publicKeys is null or undefined");
if (publicKeys.length === 0) { const agg = PublicKey.aggregate(publicKeys.map((pk) => PublicKey.fromBytes(pk)));
return Buffer.alloc(PUBLIC_KEY_LENGTH); return agg.toBytes();
}
return publicKeys
.map((p) => PublicKey.fromBytes(toBuffer(p)))
.reduce((agg, pubKey) => agg.add(pubKey))
.toBytes();
} }
/** /**

View File

@ -27,7 +27,8 @@ export class PrivateKey {
} }
static fromKeygen(entropy?: Uint8Array): PrivateKey { static fromKeygen(entropy?: Uint8Array): PrivateKey {
return this.fromBytes(generateRandomSecretKey(Buffer.from(entropy))); const sk = generateRandomSecretKey(entropy && Buffer.from(entropy));
return this.fromBytes(sk);
} }
getValue(): SecretKeyType { getValue(): SecretKeyType {

View File

@ -24,6 +24,18 @@ export class PublicKey {
return this.fromBytes(hexToBytes(hex)); return this.fromBytes(hexToBytes(hex));
} }
static aggregate(pubkeys: PublicKey[]): PublicKey {
if (pubkeys.length === 0) {
throw Error("EMPTY_AGGREGATE_ARRAY");
}
const agg = new PublicKey(pubkeys[0].value.clone());
for (const pk of pubkeys.slice(1)) {
agg.value.add(pk.value);
}
return agg;
}
add(other: PublicKey): PublicKey { add(other: PublicKey): PublicKey {
const agg = new PublicKey(this.value.clone()); const agg = new PublicKey(this.value.clone());
agg.value.add(other.value); agg.value.add(other.value);

View File

@ -28,6 +28,10 @@ export class Signature {
} }
static aggregate(signatures: Signature[]): Signature { static aggregate(signatures: Signature[]): Signature {
if (signatures.length === 0) {
throw Error("EMPTY_AGGREGATE_ARRAY");
}
const context = getContext(); const context = getContext();
const signature = new context.Signature(); const signature = new context.Signature();
signature.aggregate(signatures.map((sig) => sig.value)); signature.aggregate(signatures.map((sig) => sig.value));

View File

@ -11,9 +11,9 @@ interface IAggregateSigsTestCase {
}; };
} }
forEachImplementation((bls, implementation) => { forEachImplementation((bls) => {
describeDirectorySpecTest<IAggregateSigsTestCase, string>( describeDirectorySpecTest<IAggregateSigsTestCase, string>(
`${implementation} - bls/aggregate/small`, "bls/aggregate/small",
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate/small"), path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate/small"),
(testCase) => { (testCase) => {
try { try {

View File

@ -15,9 +15,9 @@ interface IAggregateSigsVerifyTestCase {
}; };
} }
forEachImplementation((bls, implementation) => { forEachImplementation((bls) => {
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>( describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
`${implementation} - bls/aggregate_verify/small`, "bls/aggregate_verify/small",
path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate_verify/small"), path.join(SPEC_TESTS_DIR, "general/phase0/bls/aggregate_verify/small"),
(testCase) => { (testCase) => {
const {pubkeys, messages, signature} = testCase.data.input; const {pubkeys, messages, signature} = testCase.data.input;

View File

@ -15,9 +15,9 @@ interface IAggregateSigsVerifyTestCase {
}; };
} }
forEachImplementation((bls, implementation) => { forEachImplementation((bls) => {
describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>( describeDirectorySpecTest<IAggregateSigsVerifyTestCase, boolean>(
`${implementation} - bls/fast_aggregate_verify/small`, "bls/fast_aggregate_verify/small",
path.join(SPEC_TESTS_DIR, "general/phase0/bls/fast_aggregate_verify/small"), path.join(SPEC_TESTS_DIR, "general/phase0/bls/fast_aggregate_verify/small"),
(testCase) => { (testCase) => {
const {pubkeys, message, signature} = testCase.data.input; const {pubkeys, message, signature} = testCase.data.input;

View File

@ -14,9 +14,9 @@ interface ISignMessageTestCase {
}; };
} }
forEachImplementation((bls, implementation) => { forEachImplementation((bls) => {
describeDirectorySpecTest<ISignMessageTestCase, string>( describeDirectorySpecTest<ISignMessageTestCase, string>(
`${implementation} - bls/sign/small`, "bls/sign/small",
path.join(SPEC_TESTS_DIR, "general/phase0/bls/sign/small"), path.join(SPEC_TESTS_DIR, "general/phase0/bls/sign/small"),
(testCase) => { (testCase) => {
const {privkey, message} = testCase.data.input; const {privkey, message} = testCase.data.input;

View File

@ -15,9 +15,9 @@ interface IVerifyTestCase {
}; };
} }
forEachImplementation((bls, implementation) => { forEachImplementation((bls) => {
describeDirectorySpecTest<IVerifyTestCase, boolean>( describeDirectorySpecTest<IVerifyTestCase, boolean>(
`${implementation} - bls/verify/small`, "bls/verify/small",
path.join(SPEC_TESTS_DIR, "general/phase0/bls/verify/small"), path.join(SPEC_TESTS_DIR, "general/phase0/bls/verify/small"),
(testCase) => { (testCase) => {
const {pubkey, message, signature} = testCase.data.input; const {pubkey, message, signature} = testCase.data.input;

View File

@ -17,14 +17,16 @@ export function forEachImplementation(
callback: (bls: ReturnType<typeof getBls>, implementation: Implementation) => void callback: (bls: ReturnType<typeof getBls>, implementation: Implementation) => void
): void { ): void {
for (const implementation of implementations) { for (const implementation of implementations) {
const bls = getBls(implementation); describe(implementation, () => {
const bls = getBls(implementation);
if (implementation === "herumi") { if (implementation === "herumi") {
before(async () => { before(async () => {
await bls.initBLS(); await bls.initBLS();
}); });
} }
callback(bls, implementation); callback(bls, implementation);
});
} }
} }

View File

@ -1,195 +1,105 @@
import {aggregatePubkeys, aggregateSignatures, initBLS, Keypair, verify, verifyMultiple} from "../../src";
import SHA256 from "@chainsafe/as-sha256";
import {expect} from "chai"; import {expect} from "chai";
import {forEachImplementation} from "../switch";
import {getRandomBytes} from "../../src/helpers/utils";
describe("test bls", function () { function randomMessage(): Uint8Array {
before(async function () { return getRandomBytes(32);
await initBLS(); }
});
describe("verify", function () { function getN<T>(n: number, getter: () => T): T[] {
return Array.from({length: n}, () => getter());
}
forEachImplementation((bls) => {
function getRandomData() {
const sk = bls.PrivateKey.fromKeygen();
const pk = sk.toPublicKey();
const msg = randomMessage();
const sig = sk.signMessage(msg);
return {sk, pk, msg, sig};
}
describe("verify", () => {
it("should verify signature", () => { it("should verify signature", () => {
const keypair = Keypair.generate(); const {pk, msg, sig} = getRandomData();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test"))); const pkHex = pk.toHex();
const signature = keypair.privateKey.signMessage(messageHash); const isValid = bls.verify(pk.toBytes(), msg, sig.toBytes());
const result = verify(keypair.publicKey.toBytes(), messageHash, signature.toBytes()); expect(isValid, "fail verify").to.be.true;
expect(result).to.be.true;
});
it("should not modify original pubkey when verifying", () => { // Make sure to not modify original pubkey when verifying
const keypair = Keypair.generate(); expect(pk.toHex()).to.be.equal(pkHex, "pubkey modified when verifying");
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test")));
const signature = keypair.privateKey.signMessage(messageHash);
const pubKey = keypair.publicKey.toBytes();
verify(pubKey, messageHash, signature.toBytes());
expect("0x" + pubKey.toString("hex")).to.be.equal(keypair.publicKey.toHex());
}); });
it("should fail verify empty signature", () => { it("should fail verify empty signature", () => {
const keypair = Keypair.generate(); const {pk, msg} = getRandomData();
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2"))); const emptySig = Buffer.alloc(96);
const signature = Buffer.alloc(96); const isValid = bls.verify(pk.toBytes(), msg, emptySig);
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature); expect(isValid).to.be.false;
expect(result).to.be.false;
}); });
it("should fail verify signature of different message", () => { it("should fail verify signature of different message", () => {
const keypair = Keypair.generate(); const {pk, sig} = getRandomData();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message"))); const msg2 = randomMessage();
const messageHash2 = Buffer.from(SHA256.digest(Buffer.from("Test message2"))); const isValid = bls.verify(pk.toBytes(), msg2, sig.toBytes());
const signature = keypair.privateKey.signMessage(messageHash); expect(isValid).to.be.false;
const result = verify(keypair.publicKey.toBytes(), messageHash2, signature.toBytes());
expect(result).to.be.false;
}); });
it("should fail verify signature signed by different key", () => { it("should fail verify signature signed by different key", () => {
const keypair = Keypair.generate(); const {msg, sig} = getRandomData();
const keypair2 = Keypair.generate(); const {pk: pk2} = getRandomData();
const messageHash = Buffer.from(SHA256.digest(Buffer.from("Test message"))); const isValid = bls.verify(pk2.toBytes(), msg, sig.toBytes());
const signature = keypair.privateKey.signMessage(messageHash); expect(isValid).to.be.false;
const result = verify(keypair2.publicKey.toBytes(), messageHash, signature.toBytes());
expect(result).to.be.false;
}); });
}); });
describe("verify multiple", function () { describe("verify multiple", () => {
it("should verify aggregated signatures", function () { it(`should verify aggregated signatures`, () => {
this.timeout(5000); const sks = getN(4, () => bls.PrivateKey.fromKeygen());
const msgs = getN(2, () => randomMessage());
const pks = sks.map((sk) => sk.toPublicKey());
const keypair1 = Keypair.generate(); const sigs = [
const keypair2 = Keypair.generate(); sks[0].signMessage(msgs[0]),
const keypair3 = Keypair.generate(); sks[1].signMessage(msgs[0]),
const keypair4 = Keypair.generate(); sks[2].signMessage(msgs[1]),
sks[3].signMessage(msgs[1]),
];
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const aggPubkeys = [
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2"))); bls.aggregatePubkeys([pks[0], pks[1]].map((pk) => pk.toBytes())),
bls.aggregatePubkeys([pks[2], pks[3]].map((pk) => pk.toBytes())),
];
const signature1 = keypair1.privateKey.signMessage(message1); const aggSig = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]); expect(bls.verifyMultiple(aggPubkeys, msgs, aggSig), "should be valid").to.be.true;
expect(bls.verifyMultiple(aggPubkeys.reverse(), msgs, aggSig), "should fail - swaped pubkeys").to.be.false;
const aggregatePubKey34 = aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
const aggregateSignature = aggregateSignatures([
signature1.toBytes(),
signature2.toBytes(),
signature3.toBytes(),
signature4.toBytes(),
]);
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message1, message2], aggregateSignature);
expect(result).to.be.true;
}); });
it("should verify aggregated signatures - same message", function () { it("should verify aggregated signatures - same message", () => {
this.timeout(5000); const n = 4;
const msg = randomMessage();
const sks = getN(n, () => bls.PrivateKey.fromKeygen());
const pks = sks.map((sk) => sk.toPublicKey());
const sigs = sks.map((sk) => sk.signMessage(msg));
const keypair1 = Keypair.generate(); const aggregateSignature = bls.aggregateSignatures(sigs.map((sig) => sig.toBytes()));
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
const keypair4 = Keypair.generate();
const message = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const isValid = bls.verifyMultiple(
pks.map((pk) => pk.toBytes()),
const signature1 = keypair1.privateKey.signMessage(message); getN(4, () => msg), // Same message n times
const signature2 = keypair2.privateKey.signMessage(message);
const signature3 = keypair3.privateKey.signMessage(message);
const signature4 = keypair4.privateKey.signMessage(message);
const aggregateSignature = aggregateSignatures([
signature1.toBytes(),
signature2.toBytes(),
signature3.toBytes(),
signature4.toBytes(),
]);
const result = verifyMultiple(
[
keypair1.publicKey.toBytes(),
keypair2.publicKey.toBytes(),
keypair3.publicKey.toBytes(),
keypair4.publicKey.toBytes(),
],
[message, message, message, message],
aggregateSignature aggregateSignature
); );
expect(isValid).to.be.true;
expect(result).to.be.true;
});
it("should fail to verify aggregated signatures - swapped messages", function () {
this.timeout(5000);
const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
const keypair4 = Keypair.generate();
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1);
const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
const aggregatePubKey34 = aggregatePubkeys([keypair3.publicKey.toBytes(), keypair4.publicKey.toBytes()]);
const aggregateSignature = aggregateSignatures([
signature1.toBytes(),
signature2.toBytes(),
signature3.toBytes(),
signature4.toBytes(),
]);
const result = verifyMultiple([aggregatePubKey12, aggregatePubKey34], [message2, message1], aggregateSignature);
expect(result).to.be.false;
});
it("should fail to verify aggregated signatures - different pubkeys and messsages", () => {
const keypair1 = Keypair.generate();
const keypair2 = Keypair.generate();
const keypair3 = Keypair.generate();
const keypair4 = Keypair.generate();
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1")));
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2")));
const signature1 = keypair1.privateKey.signMessage(message1);
const signature2 = keypair2.privateKey.signMessage(message1);
const signature3 = keypair3.privateKey.signMessage(message2);
const signature4 = keypair4.privateKey.signMessage(message2);
const aggregatePubKey12 = aggregatePubkeys([keypair1.publicKey.toBytes(), keypair2.publicKey.toBytes()]);
const aggregateSignature = aggregateSignatures([
signature1.toBytes(),
signature2.toBytes(),
signature3.toBytes(),
signature4.toBytes(),
]);
const result = verifyMultiple([aggregatePubKey12], [message2, message1], aggregateSignature);
expect(result).to.be.false;
}); });
it("should fail to verify aggregated signatures - no public keys", () => { it("should fail to verify aggregated signatures - no public keys", () => {
const signature = Buffer.alloc(96); const sig = Buffer.alloc(96);
const msg1 = randomMessage();
const msg2 = randomMessage();
const message1 = Buffer.from(SHA256.digest(Buffer.from("Test1"))); const isValid = bls.verifyMultiple([], [msg2, msg1], sig);
const message2 = Buffer.from(SHA256.digest(Buffer.from("Test2"))); expect(isValid).to.be.false;
const result = verifyMultiple([], [message2, message1], signature);
expect(result).to.be.false;
}); });
}); });
}); });

View File

@ -1,29 +0,0 @@
import {PrivateKey, PublicKey, Keypair, destroy, initBLS} from "../../src";
import {expect} from "chai";
describe("keypair", function () {
before(async function () {
await initBLS();
});
after(function () {
destroy();
});
it("should create from private and public key", () => {
const secret = PrivateKey.fromKeygen();
const secret2 = PrivateKey.fromKeygen();
const publicKey = PublicKey.fromBytes(secret2.toPublicKey().toBytes());
const keypair = new Keypair(secret, publicKey);
expect(keypair.publicKey).to.be.equal(publicKey);
expect(keypair.privateKey).to.be.equal(secret);
expect(keypair.privateKey).to.not.be.equal(secret2);
});
it("should create from private", () => {
const secret = PrivateKey.fromKeygen();
const publicKey = secret.toPublicKey();
const keypair = new Keypair(secret);
expect(keypair.publicKey.toBytes().toString("hex")).to.be.equal(publicKey.toBytes().toString("hex"));
});
});

View File

@ -1,36 +1,26 @@
import {PrivateKey, initBLS, destroy, SECRET_KEY_LENGTH} from "../../src";
import {expect} from "chai"; import {expect} from "chai";
import {forEachImplementation} from "../switch";
describe("privateKey", function () { forEachImplementation((bls) => {
before(async function () { describe("PrivateKey", () => {
await initBLS(); it("should generate fromKeygen private key", () => {
}); const privateKey1 = bls.PrivateKey.fromKeygen();
const privateKey2 = bls.PrivateKey.fromKeygen();
expect(privateKey1.toHex()).to.not.be.equal(privateKey2.toHex());
});
after(function () {
destroy();
});
it("should generate fromKeygen private key", function () {
const privateKey1 = PrivateKey.fromKeygen();
const privateKey2 = PrivateKey.fromKeygen();
expect(privateKey1.toHex()).to.not.be.equal(privateKey2.toHex());
});
it("should export private key to hex string", function () {
const privateKey = "0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7"; const privateKey = "0x07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7";
expect(PrivateKey.fromHex(privateKey).toHex()).to.be.equal(privateKey); it("should export private key to hex string", () => {
expect(bls.PrivateKey.fromHex(privateKey).toHex()).to.be.equal(privateKey);
});
const privateKey2 = "07656fd676da43883d163f49566c72b9cbf0a5a294f26808c807700732456da7"; it("should export private key to hex string from non-prefixed hex", () => {
expect(bls.PrivateKey.fromHex(privateKey.replace("0x", "")).toHex()).to.be.equal(privateKey);
});
expect(PrivateKey.fromHex(privateKey2).toHex()).to.be.equal(privateKey); it("should not accept too short private key", () => {
}); expect(() => bls.PrivateKey.fromHex("0x2123")).to.throw();
});
it("should export private key to bytes", function () {
expect(PrivateKey.fromKeygen().toBytes().length).to.be.equal(SECRET_KEY_LENGTH);
});
it("should not accept too short private key", function () {
expect(() => PrivateKey.fromHex("0x2123")).to.throw();
}); });
}); });

View File

@ -1,28 +1,21 @@
import {PublicKey, PrivateKey, initBLS, destroy} from "../../src";
import {expect} from "chai"; import {expect} from "chai";
import {forEachImplementation} from "../switch";
describe("public key", function () { forEachImplementation((bls) => {
before(async function f() { describe("PublicKey", () => {
await initBLS();
});
after(function () {
destroy();
});
it("from hex", function () {
const publicKey = const publicKey =
"0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311"; "0xb6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311";
expect(PublicKey.fromHex(publicKey).toHex()).to.be.equal(publicKey);
});
it("from bytes", function () { it("should export public key to hex string", () => {
const publicKey = expect(bls.PublicKey.fromHex(publicKey).toHex()).to.be.equal(publicKey);
"b6f21199594b56d77670564bf422cb331d5281ca2c1f9a45588a56881d8287ef8619efa6456d6cd2ef61306aa5b21311"; });
expect(PublicKey.fromBytes(Buffer.from(publicKey, "hex")).toHex()).to.be.equal(`0x${publicKey}`);
});
it("from private key", function () { it("should export public key to hex string from non-prefixed hex", () => {
PrivateKey.fromKeygen().toPublicKey(); expect(bls.PublicKey.fromHex(publicKey.replace("0x", "")).toHex()).to.be.equal(publicKey);
});
it("from private key", () => {
bls.PrivateKey.fromKeygen().toPublicKey();
});
}); });
}); });

View File

@ -2,11 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
"@assemblyscript/loader@^0.9.2":
version "0.9.2"
resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.9.2.tgz#5e1563c9bb5839ff9c8b3ae667e9255d8a166a37"
integrity sha512-fSt+ARVyhRwtqYUcFaLP2LUQ3DRHTsE6V9I2Iw7xaxop1ryePEaCcctIzHspvthww/2RVgtBIbmf/ICDZWkcLw==
"@babel/cli@^7.8.4": "@babel/cli@^7.8.4":
version "7.8.4" version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c" resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.8.4.tgz#505fb053721a98777b2b175323ea4f090b7d3c1c"
@ -791,14 +786,6 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@chainsafe/as-sha256@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.2.0.tgz#3ebe061d59d30af9e95a8c22ff4813cbf0e89dbc"
integrity sha512-reKklZhY4jSj7JdxdAjUfsaiMt2pdm8V/IqlOR5c4m6Y4tRCxt4f0HBMfyiE2ZQF4tqPPqRVf/ulXwK+LjLIxw==
dependencies:
"@assemblyscript/loader" "^0.9.2"
buffer "^5.4.3"
"@chainsafe/bls-hd-key@^0.1.0": "@chainsafe/bls-hd-key@^0.1.0":
version "0.1.0" version "0.1.0"
resolved "https://registry.yarnpkg.com/@chainsafe/bls-hd-key/-/bls-hd-key-0.1.0.tgz#5e51de16801f4b4b421e418f0d1ef0692df0c585" resolved "https://registry.yarnpkg.com/@chainsafe/bls-hd-key/-/bls-hd-key-0.1.0.tgz#5e51de16801f4b4b421e418f0d1ef0692df0c585"