From d80ba03c418a19b7891b1b7f12712e09f02e4f5c Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 27 Jun 2023 16:08:37 +0800 Subject: [PATCH 01/11] feat: multi tag tss --- packages/core/src/core.ts | 22 +++++++++++++- packages/default/test/helpers.js | 10 ++++-- packages/default/test/shared.js | 52 ++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 6517335f..3841f2d2 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -354,7 +354,9 @@ class ThresholdKey implements ITKey { if (useTSS) { if (!this.metadata.tssPolyCommits[this.tssTag]) { // if tss shares have not been created for this tssTag, create new tss sharing - await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub); + const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub, deviceTSSIndex); + this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs }); + await this._syncShareMetadata(); } } @@ -458,6 +460,23 @@ class ThresholdKey implements ITKey { return this.getTSSCommits()[0]; } + setTssTag(tssTag: string): void { + this.tssTag = tssTag; + } + + async createTaggedTSSShare(tssTag: string, factorPub: Point, tssShare: BN, tssIndex: number) { + if (!this.privKey) throw CoreError.default("tkey must be reconstructed"); + const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(tssTag, tssShare, factorPub, tssIndex); + await this.metadata.addTSSData({ + tssTag, + tssNonce: 0, + tssPolyCommits, + factorPubs, + factorEncs, + }); + await this._syncShareMetadata(); + } + /** * catchupToLatestShare recursively loops fetches metadata of the provided share and checks if there is an encrypted share for it. * @param shareStore - share to start of with @@ -1434,6 +1453,7 @@ class ThresholdKey implements ITKey { const shareArray = this.getAllShareStoresForLatestPolynomial().map((x) => x.share.share); await this.syncMultipleShareMetadata(shareArray, adjustScopedStore); + if (!this.manualSync) await this.syncLocalMetadataTransitions(); } async syncMultipleShareMetadata(shares: BN[], adjustScopedStore?: (ss: unknown) => unknown): Promise { diff --git a/packages/default/test/helpers.js b/packages/default/test/helpers.js index cbbf3d8c..f768bf5c 100644 --- a/packages/default/test/helpers.js +++ b/packages/default/test/helpers.js @@ -51,13 +51,14 @@ export function getServiceProvider(params) { return new ServiceProviderBase({ postboxKey: isEmptyProvider ? null : PRIVATE_KEY }); } +const MockServers = [new MockServer(), new MockServer(), new MockServer(), new MockServer(), new MockServer()]; export async function setupTSSMocks(opts) { - let { serviceProvider, verifierName, verifierId, maxTSSNonceToSimulate, tssTag } = opts; + let { serviceProvider, verifierName, verifierId, maxTSSNonceToSimulate, tssTag, postboxKey } = opts; tssTag = tssTag || "default"; serviceProvider._setVerifierNameVerifierId(verifierName, verifierId); const vid = serviceProvider.getVerifierNameVerifierId(); maxTSSNonceToSimulate = maxTSSNonceToSimulate || 1; - const serverEndpoints = [new MockServer(), new MockServer(), new MockServer(), new MockServer(), new MockServer()]; + const serverEndpoints = MockServers; const serverCount = serverEndpoints.length; const serverPrivKeys = []; for (let i = 0; i < serverCount; i++) { @@ -96,6 +97,11 @@ export async function setupTSSMocks(opts) { } serviceProvider._setTSSNodeDetails(serverEndpoints, serverPubKeys, serverThreshold); + // serviceProvider.rs = { ...serviceProvider.sssEndpoints } + if (!postboxKey) { + const postboxKeyGenerated = new BN(generatePrivate()); + serviceProvider.postboxKey = postboxKeyGenerated.toString(16, 64); + } return { serverEndpoints, diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index 3859729b..85b016cc 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -82,32 +82,58 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { verifierId: sp.verifierId, }); sp.postboxKey = postboxkey; + const newTag = "testTag"; + const { serverDKGPrivKeys } = await assignTssDkgKeys({ serviceProvider: sp, verifierName: sp.verifierName, verifierId: sp.verifierId, - maxTSSNonceToSimulate: 2, + maxTSSNonceToSimulate: 3, + // tssTag: newTag, }); + + const { serverDKGPrivKeys: serverKey1 } = await assignTssDkgKeys({ + serviceProvider: sp, + verifierName: sp.verifierName, + verifierId: sp.verifierId, + maxTSSNonceToSimulate: 3, + tssTag: newTag, + }); + const storageLayer = initStorageLayer({ hostUrl: metadataURL }); const tb1 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); + // tb1.setTssTag(newTag); // factor key needs to passed from outside of tKey const factorKey = new BN(generatePrivate()); const factorPub = getPubKeyPoint(factorKey); - await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); - const newShare = await tb1.generateNewShare(); + // await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); + await tb1.initialize(); const reconstructedKey = await tb1.reconstructKey(); + await tb1.createTaggedTSSShare("default", factorPub, deviceTSSShare, deviceTSSIndex); + + const deviceTSSShareTag = new BN(generatePrivate()); + const deviceTSSIndexTag = 2; + const factorKeyTag = new BN(generatePrivate()); + const factorPubTag = getPubKeyPoint(factorKeyTag); + tb1.setTssTag(newTag); + await tb1.createTaggedTSSShare(newTag, factorPubTag, deviceTSSShareTag, deviceTSSIndexTag); + + const newShare = await tb1.generateNewShare(); await tb1.syncLocalMetadataTransitions(); if (tb1.privKey.cmp(reconstructedKey.privKey) !== 0) { fail("key should be able to be reconstructed"); } + const tb2 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); - await tb2.initialize({ useTSS: true, factorPub }); - tb2.inputShareStore(newShare.newShareStores[newShare.newShareIndex.toString("hex")]); + // tb2.setTssTag(newTag); + await tb2.initialize(); + await tb2.inputShareStoreSafe(newShare.newShareStores[newShare.newShareIndex.toString("hex")]); await tb2.reconstructKey(); const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb2.getTSSShare(factorKey); + const tssCommits = tb2.getTSSCommits(); const tssPrivKey = getLagrangeCoeffs([1, retrievedTSSIndex], 1) .mul(serverDKGPrivKeys[0]) @@ -118,13 +144,27 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { strictEqual(tssPubKey.x.toString(16, 64), tssCommits[0].x.toString(16, 64)); strictEqual(tssPubKey.y.toString(16, 64), tssCommits[0].y.toString(16, 64)); - // // test tss refresh + // set tkey to new TSS Tag + tb2.setTssTag(newTag); + const { tssShare: retrievedTSSTag, tssIndex: retrievedTSSIndexTag } = await tb2.getTSSShare(factorKeyTag); + + const tssCommitsTag = tb2.getTSSCommits(); + const tssPrivKeyTag = getLagrangeCoeffs([1, retrievedTSSIndexTag], 1) + .mul(serverKey1[0]) + .add(getLagrangeCoeffs([1, retrievedTSSIndexTag], retrievedTSSIndexTag).mul(retrievedTSSTag)) + .umod(ecCurve.n); + const tssPubKeyTag = getPubKeyPoint(tssPrivKeyTag); + strictEqual(tssPubKeyTag.x.toString(16, 64), tssCommitsTag[0].x.toString(16, 64)); + strictEqual(tssPubKeyTag.y.toString(16, 64), tssCommitsTag[0].y.toString(16, 64)); + + // // test tss refresh const factorKey2 = new BN(generatePrivate()); const factorPub2 = getPubKeyPoint(factorKey2); const factorPubs = [factorPub, factorPub2]; const { serverEndpoints, serverPubKeys } = await sp.getRSSNodeDetails(); + tb2.setTssTag("default"); await tb2._refreshTSSShares(true, retrievedTSS, retrievedTSSIndex, factorPubs, [2, 3], testId, { serverThreshold: 3, selectedServers: [1, 2, 3], From bc5f91a638f8468fd000a61602822928acd038aa Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 27 Jun 2023 16:19:25 +0800 Subject: [PATCH 02/11] fix: add checking for existing tssTag --- packages/core/src/core.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 3841f2d2..5ffc4a9c 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -466,6 +466,9 @@ class ThresholdKey implements ITKey { async createTaggedTSSShare(tssTag: string, factorPub: Point, tssShare: BN, tssIndex: number) { if (!this.privKey) throw CoreError.default("tkey must be reconstructed"); + if (!this.metadata) throw CoreError.metadataUndefined(); + if (this.metadata.factorPubs[tssTag]) throw CoreError.default(`tssTag ${tssTag} already exists`); + const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(tssTag, tssShare, factorPub, tssIndex); await this.metadata.addTSSData({ tssTag, From 471c9bf630ede06277080ec6d9a672202cbb98f1 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 27 Jun 2023 16:27:19 +0800 Subject: [PATCH 03/11] fix: api improvement --- packages/core/src/core.ts | 9 +++++---- packages/default/test/shared.js | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 5ffc4a9c..41c62e03 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -464,14 +464,15 @@ class ThresholdKey implements ITKey { this.tssTag = tssTag; } - async createTaggedTSSShare(tssTag: string, factorPub: Point, tssShare: BN, tssIndex: number) { + async createTaggedTSSShare(factorPub: Point, tssShare: BN, tssIndex: number) { if (!this.privKey) throw CoreError.default("tkey must be reconstructed"); if (!this.metadata) throw CoreError.metadataUndefined(); - if (this.metadata.factorPubs[tssTag]) throw CoreError.default(`tssTag ${tssTag} already exists`); + if (!this.tssTag) throw CoreError.default("tssTag must be set"); + if (this.metadata.factorPubs[this.tssTag]) throw CoreError.default(`tssTag ${this.tssTag} already exists`); - const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(tssTag, tssShare, factorPub, tssIndex); + const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, tssShare, factorPub, tssIndex); await this.metadata.addTSSData({ - tssTag, + tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index 85b016cc..7d7fbfbc 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -111,14 +111,14 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { // await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); await tb1.initialize(); const reconstructedKey = await tb1.reconstructKey(); - await tb1.createTaggedTSSShare("default", factorPub, deviceTSSShare, deviceTSSIndex); + await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); const deviceTSSShareTag = new BN(generatePrivate()); const deviceTSSIndexTag = 2; const factorKeyTag = new BN(generatePrivate()); const factorPubTag = getPubKeyPoint(factorKeyTag); tb1.setTssTag(newTag); - await tb1.createTaggedTSSShare(newTag, factorPubTag, deviceTSSShareTag, deviceTSSIndexTag); + await tb1.createTaggedTSSShare(factorPubTag, deviceTSSShareTag, deviceTSSIndexTag); const newShare = await tb1.generateNewShare(); await tb1.syncLocalMetadataTransitions(); @@ -126,7 +126,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { fail("key should be able to be reconstructed"); } - const tb2 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); // tb2.setTssTag(newTag); await tb2.initialize(); From 245d10dd68143894dad7fec7d2d1ed29a2ef4c70 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 27 Jun 2023 18:27:37 +0800 Subject: [PATCH 04/11] fix: add back existing test --- packages/default/test/shared.js | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index 7d7fbfbc..a66157ce 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -69,6 +69,90 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { it("#should be able to refresh tss shares", async function () { const sp = customSP; if (!sp.useTSS) this.skip(); + const deviceTSSShare = new BN(generatePrivate()); + const deviceTSSIndex = 2; + sp.verifierName = "torus-test-health"; + sp.verifierId = "test19@example.com"; + const testId = sp.getVerifierNameVerifierId(); + const { signatures, postboxkey } = await fetchPostboxKeyAndSigs({ + serviceProvider: sp, + verifierName: sp.verifierName, + verifierId: sp.verifierId, + }); + sp.postboxKey = postboxkey; + const { serverDKGPrivKeys } = await assignTssDkgKeys({ + serviceProvider: sp, + verifierName: sp.verifierName, + verifierId: sp.verifierId, + maxTSSNonceToSimulate: 2, + }); + const storageLayer = initStorageLayer({ hostUrl: metadataURL }); + const tb1 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); + + // factor key needs to passed from outside of tKey + const factorKey = new BN(generatePrivate()); + const factorPub = getPubKeyPoint(factorKey); + + await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); + const newShare = await tb1.generateNewShare(); + const reconstructedKey = await tb1.reconstructKey(); + + await tb1.syncLocalMetadataTransitions(); + if (tb1.privKey.cmp(reconstructedKey.privKey) !== 0) { + fail("key should be able to be reconstructed"); + } + + const tb2 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); + await tb2.initialize({ useTSS: true, factorPub }); + tb2.inputShareStore(newShare.newShareStores[newShare.newShareIndex.toString("hex")]); + await tb2.reconstructKey(); + const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb2.getTSSShare(factorKey); + const tssCommits = tb2.getTSSCommits(); + const tssPrivKey = getLagrangeCoeffs([1, retrievedTSSIndex], 1) + .mul(serverDKGPrivKeys[0]) + .add(getLagrangeCoeffs([1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) + .umod(ecCurve.n); + const tssPubKey = getPubKeyPoint(tssPrivKey); + strictEqual(tssPubKey.x.toString(16, 64), tssCommits[0].x.toString(16, 64)); + strictEqual(tssPubKey.y.toString(16, 64), tssCommits[0].y.toString(16, 64)); + + const factorKey2 = new BN(generatePrivate()); + const factorPub2 = getPubKeyPoint(factorKey2); + + const factorPubs = [factorPub, factorPub2]; + const { serverEndpoints, serverPubKeys } = await sp.getRSSNodeDetails(); + await tb2._refreshTSSShares(true, retrievedTSS, retrievedTSSIndex, factorPubs, [2, 3], testId, { + serverThreshold: 3, + selectedServers: [1, 2, 3], + serverEndpoints, + serverPubKeys, + authSignatures: signatures, + }); + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); + const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) + .mul(new BN(serverDKGPrivKeys[1], "hex")) + .add(getLagrangeCoeffs([1, 2], 2).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKey.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey2); + const newTSSPrivKey = getLagrangeCoeffs([1, 3], 1) + .mul(new BN(serverDKGPrivKeys[1], "hex")) + .add(getLagrangeCoeffs([1, 3], 3).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKey.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } + }); + + it("#should be able to refresh with multiple tagged tss shares", async function () { + const sp = customSP; + if (!sp.useTSS) this.skip(); const deviceTSSShare = new BN(generatePrivate()); const deviceTSSIndex = 2; @@ -193,6 +277,41 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { // eslint-disable-next-line no-console console.log("newTSS2", newTSS2.toString("hex"), tssIndex); } + + const factorKey2Tag = new BN(generatePrivate()); + const factorPub2Tag = getPubKeyPoint(factorKey2Tag); + const factorPubsTag = [factorPubTag, factorPub2Tag]; + + tb2.setTssTag(newTag); + await tb2._refreshTSSShares(true, retrievedTSSTag, retrievedTSSIndexTag, factorPubsTag, [2, 3], testId, { + serverThreshold: 3, + selectedServers: [1, 2, 3], + serverEndpoints, + serverPubKeys, + authSignatures: signatures, + }); + + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKeyTag); + const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) + .mul(new BN(serverKey1[1], "hex")) + .add(getLagrangeCoeffs([1, 2], 2).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKeyTag.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } + + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey2Tag); + const newTSSPrivKey = getLagrangeCoeffs([1, 3], 1) + .mul(new BN(serverKey1[1], "hex")) + .add(getLagrangeCoeffs([1, 3], 3).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKeyTag.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } }); it("#should be able to reconstruct tssShare from factor key (tss2) when initializing a key with useTSS true", async function () { const sp = customSP; From 9a6fb6a9365900ba341d5106282157b97cbdb97c Mon Sep 17 00:00:00 2001 From: ieow Date: Wed, 5 Jul 2023 17:35:39 +0800 Subject: [PATCH 05/11] feat: multi tags tss refresh all --- packages/default/test/shared.js | 183 +++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 3 deletions(-) diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index a66157ce..0ffc45cf 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -20,7 +20,16 @@ import { createSandbox } from "sinon"; import { keccak256 } from "web3-utils"; import ThresholdKey from "../src/index"; -import { assignTssDkgKeys, fetchPostboxKeyAndSigs, getMetadataUrl, getServiceProvider, initStorageLayer, isMocked, setupTSSMocks } from "./helpers"; +import { + assignTssDkgKeys, + executeAtomicAsyncTasks, + fetchPostboxKeyAndSigs, + getMetadataUrl, + getServiceProvider, + initStorageLayer, + isMocked, + setupTSSMocks, +} from "./helpers"; const rejects = async (fn, error, msg) => { let f = () => {}; @@ -65,7 +74,7 @@ function compareReconstructedKeys(a, b, message) { export const sharedTestCases = (mode, torusSP, storageLayer) => { const customSP = torusSP; const customSL = storageLayer; - describe("TSS tests", function () { + describe.only("TSS tests", function () { it("#should be able to refresh tss shares", async function () { const sp = customSP; if (!sp.useTSS) this.skip(); @@ -176,6 +185,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { // tssTag: newTag, }); + // Setup tss share for newTag const { serverDKGPrivKeys: serverKey1 } = await assignTssDkgKeys({ serviceProvider: sp, verifierName: sp.verifierName, @@ -195,15 +205,24 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { // await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); await tb1.initialize(); const reconstructedKey = await tb1.reconstructKey(); + + const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + console.log("am1 length", JSON.stringify(am1[0]).length); await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); + const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + console.log("am2 length", JSON.stringify(am2[0]).length); + const deviceTSSShareTag = new BN(generatePrivate()); const deviceTSSIndexTag = 2; - const factorKeyTag = new BN(generatePrivate()); + const factorKeyTag = factorKey; // new BN(generatePrivate()); const factorPubTag = getPubKeyPoint(factorKeyTag); tb1.setTssTag(newTag); await tb1.createTaggedTSSShare(factorPubTag, deviceTSSShareTag, deviceTSSIndexTag); + const amNewTag = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + console.log("amNewTag length", JSON.stringify(amNewTag[0]).length); + const newShare = await tb1.generateNewShare(); await tb1.syncLocalMetadataTransitions(); if (tb1.privKey.cmp(reconstructedKey.privKey) !== 0) { @@ -256,6 +275,9 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { authSignatures: signatures, }); + const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); + console.log("amRefreshed length", JSON.stringify(amRefreshed[0]).length); + { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) @@ -278,6 +300,24 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { console.log("newTSS2", newTSS2.toString("hex"), tssIndex); } + const { tssShare: retrievedTSS3, tssIndex: retrievedTSSIndex3 } = await tb2.getTSSShare(factorKey); + const factorKey3 = new BN(generatePrivate()); + const factorPub3 = getPubKeyPoint(factorKey3); + const factorPubs2 = [factorPub, factorPub2]; + + // const { serverEndpoints, serverPubKeys } = await sp.getRSSNodeDetails(); + tb2.setTssTag("default"); + await tb2._refreshTSSShares(true, retrievedTSS3, retrievedTSSIndex3, factorPubs2, [2, 3], testId, { + serverThreshold: 3, + selectedServers: [1, 2, 3], + serverEndpoints, + serverPubKeys, + authSignatures: signatures, + }); + + const amRefreshed2 = tb2.generateAuthMetadata({ input: [tb2.metadata] }); + console.log("amRefreshed length", JSON.stringify(amRefreshed2[0]).length); + const factorKey2Tag = new BN(generatePrivate()); const factorPub2Tag = getPubKeyPoint(factorKey2Tag); const factorPubsTag = [factorPubTag, factorPub2Tag]; @@ -291,6 +331,8 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { authSignatures: signatures, }); + const amTagRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); + console.log("amTagRefreshed length", JSON.stringify(amTagRefreshed[0]).length); { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKeyTag); const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) @@ -873,6 +915,141 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { await tb3.updateSDK(); }); }); + describe.only("multi tag tss", function () { + it.only("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { + const sp = customSP; + if (!sp.useTSS) this.skip(); + + const deviceTSSShare = new BN(generatePrivate()); + const deviceTSSIndex = 2; + + sp.verifierName = "torus-test-health"; + sp.verifierId = "test19@example.com"; + const testId = sp.getVerifierNameVerifierId(); + + const { signatures, postboxkey } = await fetchPostboxKeyAndSigs({ + serviceProvider: sp, + verifierName: sp.verifierName, + verifierId: sp.verifierId, + }); + + // eslint-disable-next-line require-atomic-updates + sp.postboxKey = postboxkey; + + const tags = ["tag1", "tag2", "tag3", "tag4"]; + + const dkgKeyAssignedPromise = tags.map(async (tag) => { + const { serverDKGPrivKeys } = await assignTssDkgKeys({ + serviceProvider: sp, + verifierName: sp.verifierName, + verifierId: sp.verifierId, + maxTSSNonceToSimulate: 3, + tssTag: tag, + }); + return serverDKGPrivKeys; + }); + // await executeAtomicAsyncTasks(dkgKeyAssigned); + const dkgKeyAssigned = await Promise.all(dkgKeyAssignedPromise); + + const storageLayer = initStorageLayer({ hostUrl: metadataURL }); + const tb1 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); + // tb1.setTssTag(newTag); + + // factor key needs to passed from outside of tKey + const factorKey = new BN(generatePrivate()); + const factorPub = getPubKeyPoint(factorKey); + + // await tb1.initialize({ useTSS: true, factorPub, deviceTSSShare, deviceTSSIndex }); + await tb1.initialize(); + const reconstructedKey = await tb1.reconstructKey(); + + const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + console.log("am1 length", JSON.stringify(am1[0]).length); + + const tagTasks = tags.map((tag, index) => { + return async () => { + tb1.setTssTag(tag); + await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); + const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + console.log(`${tag} metadata length`, JSON.stringify(am2[0]).length); + }; + }); + await executeAtomicAsyncTasks(tagTasks); + + // generate new share for new instance initialization + const newShare = await tb1.generateNewShare(); + await tb1.syncLocalMetadataTransitions(); + if (tb1.privKey.cmp(reconstructedKey.privKey) !== 0) { + fail("key should be able to be reconstructed"); + } + + // new instance initialization + const tb2 = new ThresholdKey({ serviceProvider: sp, storageLayer, manualSync: mode }); + await tb2.initialize(); + await tb2.inputShareStoreSafe(newShare.newShareStores[newShare.newShareIndex.toString("hex")]); + await tb2.reconstructKey(); + + // TSS share test + const testTasks = tags.map((tag, index) => { + return async () => { + tb2.setTssTag(tag); + const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb2.getTSSShare(factorKey); + + const tssCommits = tb2.getTSSCommits(); + const tssPrivKey = getLagrangeCoeffs([1, retrievedTSSIndex], 1) + .mul(dkgKeyAssigned[index][0]) + .add(getLagrangeCoeffs([1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) + .umod(ecCurve.n); + + const tssPubKey = getPubKeyPoint(tssPrivKey); + strictEqual(tssPubKey.x.toString(16, 64), tssCommits[0].x.toString(16, 64)); + strictEqual(tssPubKey.y.toString(16, 64), tssCommits[0].y.toString(16, 64)); + + // // test tss refresh + const factorKey2 = new BN(generatePrivate()); + const factorPub2 = getPubKeyPoint(factorKey2); + + const factorPubs = [factorPub, factorPub2]; + const { serverEndpoints, serverPubKeys } = await sp.getRSSNodeDetails(); + + await tb2._refreshTSSShares(true, retrievedTSS, retrievedTSSIndex, factorPubs, [2, 3], testId, { + serverThreshold: 3, + selectedServers: [1, 2, 3], + serverEndpoints, + serverPubKeys, + authSignatures: signatures, + }); + + const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); + console.log(` Tags tss ${tag} Refreshed length`, JSON.stringify(amRefreshed[0]).length); + + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); + const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) + .mul(new BN(dkgKeyAssigned[index][1], "hex")) + .add(getLagrangeCoeffs([1, 2], 2).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKey.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } + + { + const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey2); + const newTSSPrivKey = getLagrangeCoeffs([1, 3], 1) + .mul(new BN(dkgKeyAssigned[index][1], "hex")) + .add(getLagrangeCoeffs([1, 3], 3).mul(newTSS2)) + .umod(ecCurve.n); + strictEqual(tssPrivKey.toString(16, 64), newTSSPrivKey.toString(16, 64)); + // eslint-disable-next-line no-console + console.log("newTSS2", newTSS2.toString("hex"), tssIndex); + } + }; + }); + + await executeAtomicAsyncTasks(testTasks); + }); + }); }); describe("tkey", function () { let tb; From 0a0dc9ffb450e00e227c9e486abeaf9151529414 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 11 Jul 2023 15:40:06 +0800 Subject: [PATCH 06/11] fix: add missing function executeAtomicAsyncTasks --- packages/default/test/helpers.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/default/test/helpers.js b/packages/default/test/helpers.js index f768bf5c..ff81c848 100644 --- a/packages/default/test/helpers.js +++ b/packages/default/test/helpers.js @@ -188,3 +188,9 @@ export async function assignTssDkgKeys(opts) { // serverDKGPubKeys, }; } + +export async function executeAtomicAsyncTasks(tasks) { + for (const task of tasks) { + await task(); // Assuming task is an async function + } +} From fd0e5581b91965cc4b6544d0cc36575605e94e70 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 11 Jul 2023 15:49:08 +0800 Subject: [PATCH 07/11] fix: cleanup console.log --- packages/default/test/shared.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index 0ffc45cf..893a0726 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -74,7 +74,7 @@ function compareReconstructedKeys(a, b, message) { export const sharedTestCases = (mode, torusSP, storageLayer) => { const customSP = torusSP; const customSL = storageLayer; - describe.only("TSS tests", function () { + describe("TSS tests", function () { it("#should be able to refresh tss shares", async function () { const sp = customSP; if (!sp.useTSS) this.skip(); @@ -207,11 +207,9 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { const reconstructedKey = await tb1.reconstructKey(); const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); - console.log("am1 length", JSON.stringify(am1[0]).length); await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); - console.log("am2 length", JSON.stringify(am2[0]).length); const deviceTSSShareTag = new BN(generatePrivate()); const deviceTSSIndexTag = 2; @@ -221,7 +219,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { await tb1.createTaggedTSSShare(factorPubTag, deviceTSSShareTag, deviceTSSIndexTag); const amNewTag = tb1.generateAuthMetadata({ input: [tb1.metadata] }); - console.log("amNewTag length", JSON.stringify(amNewTag[0]).length); const newShare = await tb1.generateNewShare(); await tb1.syncLocalMetadataTransitions(); @@ -276,7 +273,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); - console.log("amRefreshed length", JSON.stringify(amRefreshed[0]).length); { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); @@ -316,7 +312,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); const amRefreshed2 = tb2.generateAuthMetadata({ input: [tb2.metadata] }); - console.log("amRefreshed length", JSON.stringify(amRefreshed2[0]).length); const factorKey2Tag = new BN(generatePrivate()); const factorPub2Tag = getPubKeyPoint(factorKey2Tag); @@ -332,7 +327,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); const amTagRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); - console.log("amTagRefreshed length", JSON.stringify(amTagRefreshed[0]).length); { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKeyTag); const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1) @@ -915,8 +909,8 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { await tb3.updateSDK(); }); }); - describe.only("multi tag tss", function () { - it.only("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { + describe("multi tag tss", function () { + it("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { const sp = customSP; if (!sp.useTSS) this.skip(); @@ -964,14 +958,12 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { const reconstructedKey = await tb1.reconstructKey(); const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); - console.log("am1 length", JSON.stringify(am1[0]).length); const tagTasks = tags.map((tag, index) => { return async () => { tb1.setTssTag(tag); await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); - console.log(`${tag} metadata length`, JSON.stringify(am2[0]).length); }; }); await executeAtomicAsyncTasks(tagTasks); @@ -1021,7 +1013,6 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); - console.log(` Tags tss ${tag} Refreshed length`, JSON.stringify(amRefreshed[0]).length); { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); From 6274cf0430caaa1882ba3d72609ada94ffe92640 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 11 Jul 2023 15:54:14 +0800 Subject: [PATCH 08/11] fix: revert changes. Initialized tkey could not update tkey metadata --- packages/core/src/core.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 41c62e03..d45c1fd3 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -354,9 +354,7 @@ class ThresholdKey implements ITKey { if (useTSS) { if (!this.metadata.tssPolyCommits[this.tssTag]) { // if tss shares have not been created for this tssTag, create new tss sharing - const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub, deviceTSSIndex); - this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs }); - await this._syncShareMetadata(); + await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub, deviceTSSIndex); } } From f2519c3d96f9860966be992400d95eddc58859f8 Mon Sep 17 00:00:00 2001 From: shubham <16849485+metallicalfa2@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:21:21 +0800 Subject: [PATCH 09/11] fix: logs --- packages/core/src/core.ts | 2 +- packages/default/test/shared.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index d45c1fd3..226ced01 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -469,7 +469,7 @@ class ThresholdKey implements ITKey { if (this.metadata.factorPubs[this.tssTag]) throw CoreError.default(`tssTag ${this.tssTag} already exists`); const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, tssShare, factorPub, tssIndex); - await this.metadata.addTSSData({ + this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index 893a0726..c092967e 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -910,7 +910,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); }); describe("multi tag tss", function () { - it("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { + it.only("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { const sp = customSP; if (!sp.useTSS) this.skip(); @@ -957,13 +957,13 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { await tb1.initialize(); const reconstructedKey = await tb1.reconstructKey(); - const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + // const am1 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); const tagTasks = tags.map((tag, index) => { return async () => { tb1.setTssTag(tag); await tb1.createTaggedTSSShare(factorPub, deviceTSSShare, deviceTSSIndex); - const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); + // const am2 = tb1.generateAuthMetadata({ input: [tb1.metadata] }); }; }); await executeAtomicAsyncTasks(tagTasks); @@ -1012,7 +1012,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { authSignatures: signatures, }); - const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); + // const amRefreshed = tb2.generateAuthMetadata({ input: [tb2.metadata] }); { const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey); From 96c6d7212c53976f780a6b37e23f6b212f4edb89 Mon Sep 17 00:00:00 2001 From: shubham <16849485+metallicalfa2@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:28:17 +0800 Subject: [PATCH 10/11] fix: logs --- packages/core/src/core.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index 226ced01..1d6a6c18 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -1455,7 +1455,6 @@ class ThresholdKey implements ITKey { const shareArray = this.getAllShareStoresForLatestPolynomial().map((x) => x.share.share); await this.syncMultipleShareMetadata(shareArray, adjustScopedStore); - if (!this.manualSync) await this.syncLocalMetadataTransitions(); } async syncMultipleShareMetadata(shares: BN[], adjustScopedStore?: (ss: unknown) => unknown): Promise { From a17170f7b8d7b924fc1e787945c49d3b01a28058 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 11 Jul 2023 16:40:16 +0800 Subject: [PATCH 11/11] fix: remove 'only' --- packages/default/test/shared.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/default/test/shared.js b/packages/default/test/shared.js index c092967e..de597401 100644 --- a/packages/default/test/shared.js +++ b/packages/default/test/shared.js @@ -910,7 +910,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => { }); }); describe("multi tag tss", function () { - it.only("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { + it("#should be able to refresh with 4 tagged tss shares and refersh from 2/2 -> 2/3 ", async function () { const sp = customSP; if (!sp.useTSS) this.skip();