From 6ff795da005f44ca198d34df2357558aa8f2e58c Mon Sep 17 00:00:00 2001 From: ieow Date: Sat, 22 Feb 2025 04:19:36 +0800 Subject: [PATCH 1/3] feat: refactor to use setTssTag --- packages/tss/src/tss.ts | 123 ++++++++++--------- packages/tss/test/tssMultiCurveTestCases.ts | 75 +++++------ packages/tss/test/tssSingleCurveTestCases.ts | 72 +++++------ 3 files changed, 122 insertions(+), 148 deletions(-) diff --git a/packages/tss/src/tss.ts b/packages/tss/src/tss.ts index f9a95445..da0d963f 100644 --- a/packages/tss/src/tss.ts +++ b/packages/tss/src/tss.ts @@ -156,6 +156,10 @@ export class TKeyTSS extends TKey { return super.initialize(params); } + public setTssTag(tssTag: string) { + this._tssTag = tssTag; + } + /** * Initializes Tss Curve with Secp256k1 keyType * will use same factorPubs from Ed24459 curves if existing Ed25519 curve present @@ -189,7 +193,7 @@ export class TKeyTSS extends TKey { } const backupMetadata = this.metadata.clone(); - const localTssTag = TSS_TAG_DEFAULT; + const localTssTag = this.tssTag; try { if (!importKey) { // if tss shares have not been created for this tssTag, create new tss sharing @@ -347,18 +351,18 @@ export class TKeyTSS extends TKey { /** * Returns the encrypted data associated with the given factor public key. */ - getFactorEncs(factorPub: Point, keyType: KeyType, tssTag: string = TSS_TAG_DEFAULT): FactorEnc { - const localTssTag = tssTag; + getFactorEncs(factorPub: Point, keyType: KeyType): FactorEnc { + const { tssTag } = this; if (!this.metadata) throw CoreError.metadataUndefined(); - const tssData = this.metadata.getTssData(keyType, localTssTag); + const tssData = this.metadata.getTssData(keyType, tssTag); if (!tssData) throw CoreError.default("no factor encs mapping"); const { factorPubs } = tssData; - if (!factorPubs) throw CoreError.default(`no factor pubs for this tssTag ${localTssTag}`); + if (!factorPubs) throw CoreError.default(`no factor pubs for this tssTag ${tssTag}`); if (factorPubs.filter((f) => f.x.cmp(factorPub.x) === 0 && f.y.cmp(factorPub.y) === 0).length === 0) - throw CoreError.default(`factor pub ${factorPub} not found for tssTag ${localTssTag}`); - if (!tssData.factorEncs) throw CoreError.default(`no factor encs for tssTag ${localTssTag}`); + throw CoreError.default(`factor pub ${factorPub} not found for tssTag ${tssTag}`); + if (!tssData.factorEncs) throw CoreError.default(`no factor encs for tssTag ${tssTag}`); const factorPubID = factorPub.x.toString(16, 64); return tssData.factorEncs[factorPubID]; } @@ -370,7 +374,6 @@ export class TKeyTSS extends TKey { factorKey: BN, opts: { keyType: KeyType; - tssTag: string; threshold?: number; accountIndex?: number; coefficient?: BN; @@ -380,9 +383,8 @@ export class TKeyTSS extends TKey { tssShare: BN; }> { const factorPub = getPubKeyPoint(factorKey, factorKeyCurve); - const localTssTag = opts.tssTag; - const factorEncs = this.getFactorEncs(factorPub, opts.keyType, localTssTag); + const factorEncs = this.getFactorEncs(factorPub, opts.keyType); const { userEnc, serverEncs, tssIndex, type } = factorEncs; const userDecryption = await decrypt(Buffer.from(factorKey.toString(16, 64), "hex"), userEnc); const serverDecryptions = await Promise.all( @@ -399,7 +401,7 @@ export class TKeyTSS extends TKey { }); const ec = getKeyCurve(opts.keyType); - const tssCommits = this.getTSSCommits(opts.keyType, localTssTag).map((p) => { + const tssCommits = this.getTSSCommits(opts.keyType).map((p) => { return ec.keyFromPublic({ x: p.x.toString(16, 64), y: p.y.toString(16, 64) }).getPublic(); }); @@ -454,14 +456,14 @@ export class TKeyTSS extends TKey { * Returns the TSS public key and the curve points corresponding to secret key * shares, as stored in Metadata. */ - getTSSCommits(tssKeyType: KeyType, tssTag: string): Point[] { + getTSSCommits(tssKeyType: KeyType): Point[] { if (!this.metadata) throw CoreError.metadataUndefined(); - const localTssTag = tssTag; - const tssData = this.metadata.getTssData(tssKeyType, localTssTag); + const { tssTag } = this; + const tssData = this.metadata.getTssData(tssKeyType, tssTag); if (!tssData) throw CoreError.default("no tss data"); const { tssPolyCommits } = tssData; - if (!tssPolyCommits) throw CoreError.default(`tss poly commits not found for tssTag ${localTssTag}`); + if (!tssPolyCommits) throw CoreError.default(`tss poly commits not found for tssTag ${tssTag}`); if (tssPolyCommits.length === 0) throw CoreError.default("tss poly commits is empty"); return tssPolyCommits; } @@ -469,9 +471,9 @@ export class TKeyTSS extends TKey { /** * Returns the TSS public key. */ - getTSSPub(tssKeyType: KeyType, tssTag: string, accountIndex?: number): Point { + getTSSPub(tssKeyType: KeyType, accountIndex?: number): Point { const ec = getKeyCurve(tssKeyType); - const tssCommits = this.getTSSCommits(tssKeyType, tssTag); + const tssCommits = this.getTSSCommits(tssKeyType); if (accountIndex && accountIndex > 0) { // Add account nonce to pub key. const nonce = this.computeAccountNonce(accountIndex); @@ -525,7 +527,11 @@ export class TKeyTSS extends TKey { const { importKey, factorPubs, newTSSIndexes, tssTag, tssKeyType } = params; - const localTssTag = tssTag ?? TSS_TAG_DEFAULT; + const oldTag = this._tssTag; + + // update current tssTag + this._tssTag = tssTag; + const localTssTag = this._tssTag; const tssData = this.metadata.getTssData(params.tssKeyType, localTssTag); if (tssData) { @@ -655,9 +661,10 @@ export class TKeyTSS extends TKey { authSignatures: string[]; accountIndex?: number; keyType: KeyType; - tssTag: string; }): Promise { - const { factorKey, selectedServers, authSignatures, accountIndex, keyType, tssTag } = tssOptions; + const { factorKey, selectedServers, authSignatures, accountIndex, keyType } = tssOptions; + + const { tssTag } = this; if (!this.metadata) throw CoreError.metadataUndefined("metadata is undefined"); if (!this.secp256k1Key) throw new Error("Tkey is not reconstructed"); @@ -665,7 +672,7 @@ export class TKeyTSS extends TKey { const tssData = this.metadata.getTssData(keyType, tssTag); if (!tssData?.tssPolyCommits?.length) throw new Error(`tss key has not been initialized for tssTag ${tssTag}`); - const { tssIndex } = await this.getTSSShare(factorKey, { keyType, tssTag }); + const { tssIndex } = await this.getTSSShare(factorKey, { keyType }); // Assumption that there are only index 2 and 3 for tss shares // create complement index share const tempShareIndex = tssIndex === 2 ? 3 : 2; @@ -679,11 +686,10 @@ export class TKeyTSS extends TKey { authSignatures, selectedServers, refreshShares: true, - tssTag, }); - const { tssShare: factorShare, tssIndex: factorIndex } = await this.getTSSShare(factorKey, { keyType, tssTag }); - const { tssShare: tempShare, tssIndex: tempIndex } = await this.getTSSShare(tempFactorKey, { keyType, tssTag }); + const { tssShare: factorShare, tssIndex: factorIndex } = await this.getTSSShare(factorKey, { keyType }); + const { tssShare: tempShare, tssIndex: tempIndex } = await this.getTSSShare(tempFactorKey, { keyType }); // reconstruct final key using sss const ec = getKeyCurve(keyType); @@ -695,7 +701,6 @@ export class TKeyTSS extends TKey { deleteFactorPub: tempFactorPub, authSignatures, selectedServers, - tssTag, }); // Derive key for account index. @@ -710,16 +715,12 @@ export class TKeyTSS extends TKey { * * Reconstructs the TSS private key and exports the ed25519 private key seed. */ - async _UNSAFE_exportTssEd25519Seed(tssOptions: { - factorKey: BN; - selectedServers?: number[]; - authSignatures: string[]; - tssTag: string; - }): Promise { + async _UNSAFE_exportTssEd25519Seed(tssOptions: { factorKey: BN; selectedServers?: number[]; authSignatures: string[] }): Promise { const edScalar = await this._UNSAFE_exportTssKey({ ...tssOptions, keyType: KeyType.ed25519 }); + const { tssTag } = this; // Try to export ed25519 seed. This is only available if import key was being used. - const domainKey = getEd25519SeedStoreDomainKey(tssOptions.tssTag); + const domainKey = getEd25519SeedStoreDomainKey(tssTag); const result = this.metadata.getGeneralStoreDomain(domainKey) as Record; const decKey = getSecpKeyFromEd25519(edScalar).scalar; @@ -752,7 +753,7 @@ export class TKeyTSS extends TKey { new Array(rssNodeDetails.serverEndpoints.length).fill(null).map((_, i) => i + 1), Math.ceil(rssNodeDetails.serverEndpoints.length / 2) ); - const localTssTag = TSS_TAG_DEFAULT; + const localTssTag = this.tssTag; const verifierNameVerifierId = this.serviceProvider.getVerifierNameVerifierId(); const tssData = this.metadata.getTssData(keyType, localTssTag); if (!tssData) throw CoreError.default("no tss data"); @@ -765,7 +766,7 @@ export class TKeyTSS extends TKey { finalSelectedServers = nodeIndexes.slice(0, Math.min(serverEndpoints.length, nodeIndexes.length)); } - const factorEnc = this.getFactorEncs(Point.fromSEC1(secp256k1, remoteClient.remoteFactorPub), keyType, localTssTag); + const factorEnc = this.getFactorEncs(Point.fromSEC1(secp256k1, remoteClient.remoteFactorPub), keyType); const dataRequired: RefreshRemoteTssParams = { factorEnc, @@ -816,11 +817,11 @@ export class TKeyTSS extends TKey { }) { const { newFactorPub, newFactorTSSIndex, remoteClient, keyType, tssTag } = params; // const ed25519TssMetadata = this.metadata.getTssData(KeyType.ed25519); - const localTssTag = TSS_TAG_DEFAULT; + const localTssTag = this.tssTag; const secp256k1TssMetadata = this.metadata.getTssData(KeyType.secp256k1, localTssTag); const existingFactorPubs = secp256k1TssMetadata.factorPubs; const updatedFactorPubs = existingFactorPubs.concat([newFactorPub]); - const existingTSSIndexes = existingFactorPubs.map((fb) => this.getFactorEncs(fb, keyType, localTssTag).tssIndex); + const existingTSSIndexes = existingFactorPubs.map((fb) => this.getFactorEncs(fb, keyType).tssIndex); const updatedTSSIndexes = existingTSSIndexes.concat([newFactorTSSIndex]); await this.remoteRefreshTssShares({ @@ -832,9 +833,10 @@ export class TKeyTSS extends TKey { }); } - async remoteDeleteFactorPub(params: { factorPubToDelete: Point; remoteClient: IRemoteClientState; keyType: KeyType; tssTag: string }) { - const { factorPubToDelete, remoteClient, keyType, tssTag } = params; - const tssData = this.metadata.getTssData(keyType, tssTag); + async remoteDeleteFactorPub(params: { factorPubToDelete: Point; remoteClient: IRemoteClientState; keyType: KeyType }) { + const { factorPubToDelete, remoteClient, keyType } = params; + const localTssTag = this.tssTag; + const tssData = this.metadata.getTssData(keyType, localTssTag); const existingFactorPubs = tssData.factorPubs; const factorIndex = existingFactorPubs.findIndex((p) => p.x.eq(factorPubToDelete.x)); if (factorIndex === -1) { @@ -842,7 +844,7 @@ export class TKeyTSS extends TKey { } const updatedFactorPubs = existingFactorPubs.slice(); updatedFactorPubs.splice(factorIndex, 1); - const updatedTSSIndexes = updatedFactorPubs.map((fb) => this.getFactorEncs(fb, keyType, tssTag).tssIndex); + const updatedTSSIndexes = updatedFactorPubs.map((fb) => this.getFactorEncs(fb, keyType).tssIndex); await this.remoteRefreshTssShares({ factorPubs: updatedFactorPubs, @@ -856,9 +858,9 @@ export class TKeyTSS extends TKey { async remoteCopyFactorPub(params: { newFactorPub: Point; tssIndex: number; remoteClient: IRemoteClientState; keyType: KeyType }) { const { newFactorPub, tssIndex, remoteClient, keyType } = params; const remoteFactorPub = Point.fromSEC1(secp256k1, remoteClient.remoteFactorPub); - const localTssTag = TSS_TAG_DEFAULT; - const factorEnc = this.getFactorEncs(remoteFactorPub, keyType, localTssTag); - const tssCommits = this.getTSSCommits(keyType, localTssTag).map((commit) => commit.toPointHex()); + const localTssTag = this.tssTag; + const factorEnc = this.getFactorEncs(remoteFactorPub, keyType); + const tssCommits = this.getTSSCommits(keyType).map((commit) => commit.toPointHex()); const dataRequired: CopyRemoteTssParams = { factorEnc, tssCommits, @@ -922,7 +924,7 @@ export class TKeyTSS extends TKey { ): Promise { if (!this.metadata) throw CoreError.metadataUndefined(); const { keyType } = serverOpts; - const localTssTag = tssTag ?? TSS_TAG_DEFAULT; + const localTssTag = tssTag; const tssData = this.metadata.getTssData(keyType, localTssTag); const tssCommits = tssData?.tssPolyCommits; @@ -1091,10 +1093,10 @@ export class TKeyTSS extends TKey { authSignatures: string[]; refreshShares?: boolean; updateMetadata?: boolean; - tssTag: string; }) { - const secp256k1Data = this.metadata.getTssData(KeyType.secp256k1, args.tssTag); - const ed25519Data = this.metadata.getTssData(KeyType.ed25519, args.tssTag); + const tssTag = this._tssTag; + const secp256k1Data = this.metadata.getTssData(KeyType.secp256k1, tssTag); + const ed25519Data = this.metadata.getTssData(KeyType.ed25519, tssTag); const allPromise = []; @@ -1123,19 +1125,19 @@ export class TKeyTSS extends TKey { refreshShares?: boolean; updateMetadata?: boolean; keyType: KeyType; - tssTag: string; }) { if (!this.metadata) throw CoreError.metadataUndefined("metadata is undefined"); if (!this.secp256k1Key) throw new Error("Tkey is not reconstructed"); - const { existingFactorKey, newFactorPub, newTSSIndex, selectedServers, authSignatures, refreshShares, keyType, tssTag } = args; + const { existingFactorKey, newFactorPub, newTSSIndex, selectedServers, authSignatures, refreshShares, keyType } = args; + const tssTag = this._tssTag; const tssData = this.metadata.getTssData(keyType, tssTag); - const { tssShare, tssIndex } = await this.getTSSShare(existingFactorKey, { keyType, tssTag }); + const { tssShare, tssIndex } = await this.getTSSShare(existingFactorKey, { keyType }); if (tssIndex !== newTSSIndex && !refreshShares) { throw CoreError.default("newTSSIndex does not match existing tssIndex, set refreshShares to true to refresh shares"); } - const localTssTag = tssTag ?? TSS_TAG_DEFAULT; + const localTssTag = tssTag; if (!refreshShares) { // Just copy data stored under factor key. @@ -1173,7 +1175,7 @@ export class TKeyTSS extends TKey { const finalServer = selectedServers || randomSelectedServers; - const existingTSSIndexes = existingFactorPubs.map((fb) => this.getFactorEncs(fb, keyType, localTssTag).tssIndex); + const existingTSSIndexes = existingFactorPubs.map((fb) => this.getFactorEncs(fb, keyType).tssIndex); const updatedTSSIndexes = existingTSSIndexes.concat([newTSSIndex]); // sync metadata by default @@ -1199,7 +1201,6 @@ export class TKeyTSS extends TKey { } public async deleteFactorPub(args: { - tssTag: string; factorKey: BN; deleteFactorPub: Point; selectedServers?: number[]; @@ -1207,10 +1208,10 @@ export class TKeyTSS extends TKey { updateMetadata?: boolean; }): Promise { const { updateMetadata, ...otherArgs } = args; + const { tssTag } = this; const allPromise = []; - if (this.metadata.getTssData(KeyType.secp256k1, args.tssTag)) - allPromise.push(this._deleteFactorPub({ ...otherArgs, keyType: KeyType.secp256k1 })); - if (this.metadata.getTssData(KeyType.ed25519, args.tssTag)) allPromise.push(this._deleteFactorPub({ ...otherArgs, keyType: KeyType.ed25519 })); + if (this.metadata.getTssData(KeyType.secp256k1, tssTag)) allPromise.push(this._deleteFactorPub({ ...otherArgs, keyType: KeyType.secp256k1 })); + if (this.metadata.getTssData(KeyType.ed25519, tssTag)) allPromise.push(this._deleteFactorPub({ ...otherArgs, keyType: KeyType.ed25519 })); await Promise.all(allPromise); if (updateMetadata) await this._syncShareMetadata(); } @@ -1226,15 +1227,15 @@ export class TKeyTSS extends TKey { authSignatures: string[]; updateMetadata?: boolean; keyType: KeyType; - tssTag: string; }): Promise { if (!this.metadata) throw CoreError.metadataUndefined("metadata is undefined"); if (!this.secp256k1Key) throw new Error("Tkey is not reconstructed"); - const { factorKey, deleteFactorPub, selectedServers, authSignatures, keyType, tssTag } = args; + const { factorKey, deleteFactorPub, selectedServers, authSignatures, keyType } = args; + const tssTag = this._tssTag; const tssData = this.metadata.getTssData(keyType, tssTag); const existingFactorPubs = tssData.factorPubs; - const { tssShare, tssIndex } = await this.getTSSShare(factorKey, { keyType, tssTag }); + const { tssShare, tssIndex } = await this.getTSSShare(factorKey, { keyType }); const found = existingFactorPubs.filter((f) => f.x.eq(deleteFactorPub.x) && f.y.eq(deleteFactorPub.y)); if (found.length === 0) throw CoreError.default("could not find factorPub to delete"); @@ -1248,7 +1249,7 @@ export class TKeyTSS extends TKey { Math.ceil(rssNodeDetails.serverEndpoints.length / 2) ); const finalServer = selectedServers || randomSelectedServers; - const updatedTSSIndexes = updatedFactorPubs.map((fb) => this.getFactorEncs(fb, keyType, tssTag).tssIndex); + const updatedTSSIndexes = updatedFactorPubs.map((fb) => this.getFactorEncs(fb, keyType).tssIndex); const updateMetadata = args.updateMetadata !== undefined ? args.updateMetadata : true; @@ -1308,6 +1309,8 @@ export class TKeyTSS extends TKey { const a0Pub = tss1PubKey.mul(L1_0).add(tss2PubKey.mul(LIndex_0)); const a1Pub = tss1PubKey.add(a0Pub.neg()); + // y = mx +c + // a0Pub = c, a1Pub = y0 -y1 = m const tssPolyCommits = [Point.fromElliptic(a0Pub), Point.fromElliptic(a1Pub)]; const factorPubs = [factorPub]; const factorEncs: { [factorPubID: string]: FactorEnc } = {}; diff --git a/packages/tss/test/tssMultiCurveTestCases.ts b/packages/tss/test/tssMultiCurveTestCases.ts index 8c46459a..68592043 100644 --- a/packages/tss/test/tssMultiCurveTestCases.ts +++ b/packages/tss/test/tssMultiCurveTestCases.ts @@ -149,13 +149,13 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea if (tb1.secp256k1Key.cmp(reconstructedKey.secp256k1Key) !== 0) { fail("key should be able to be reconstructed"); } - const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); // compute public key of the tss share const tss2Pub = ecTSS.g.mul(tss2); // get tss pub key from tss commits - const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE); const tssCommitA0 = tssCommits[0].toEllipticPoint(ecTSS); const tssCommitA1 = tssCommits[1].toEllipticPoint(ecTSS); @@ -228,8 +228,8 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea fail("key should be able to be reconstructed"); } - const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); - const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); + const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], 1) .mul(tss1) @@ -238,7 +238,7 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea const tssPubKey = (ecTSS.g as EllipticPoint).mul(tssPrivKey); const tssCommits0 = tssCommits[0].toEllipticPoint(ecTSS); - const tssPub = tb1.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT).toEllipticPoint(ecTSS); + const tssPub = tb1.getTSSPub(TSS_KEY_TYPE).toEllipticPoint(ecTSS); equal(tssPubKey.eq(tssCommits0), true); equal(tssPub.eq(tssPubKey), true); @@ -250,14 +250,14 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea const nonce = tb1.computeAccountNonce(accountIndex); return share.add(nonce).umod(ecTSS.n); })(); - const { tssShare: tss2Account } = await tb1.getTSSShare(factorKey, { accountIndex, keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + const { tssShare: tss2Account } = await tb1.getTSSShare(factorKey, { accountIndex, keyType: TSS_KEY_TYPE }); const coefficient1 = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], 1); const coefficient2 = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], deviceTSSIndex); const tssKey = coefficient1.mul(tss1Account).add(coefficient2.mul(tss2Account)).umod(ecTSS.n); const tssKeyPub = (ecTSS.g as EllipticPoint).mul(tssKey); - const tssPubAccount = tb1.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT, accountIndex).toEllipticPoint(ecTSS); + const tssPubAccount = tb1.getTSSPub(TSS_KEY_TYPE, accountIndex).toEllipticPoint(ecTSS); equal(tssPubAccount.eq(tssKeyPub), true, "should equal account pub key"); } }); @@ -307,7 +307,8 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea // Check pub key. const ec = getEcCurve(TSS_KEY_TYPE); const importTssKeyPub = Point.fromScalar(importTssKey.scalar, ec); - const tssPub = await tb.getTSSPub(TSS_KEY_TYPE, "imported"); + // tb.tssTag = "imported"; + const tssPub = await tb.getTSSPub(TSS_KEY_TYPE); assert(tssPub.equals(importTssKeyPub)); // Check exported key. @@ -315,14 +316,13 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea factorKey, authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); assert(exportedKey.eq(importTssKey.scalar)); if (TSS_KEY_TYPE === KeyType.ed25519) { + tb.setTssTag(TSS_TAG_DEFAULT); const seed = await tb._UNSAFE_exportTssEd25519Seed({ factorKey, authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); assert(seed.equals(importTssKey.raw)); } else { @@ -332,10 +332,9 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea authSignatures: signatures, accountIndex: 2, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const exportedPubKeyIndex2 = Point.fromScalar(exportedKeyIndex2, ec); - const pubKeyIndex2 = tb.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT, 2); + const pubKeyIndex2 = tb.getTSSPub(TSS_KEY_TYPE, 2); assert(exportedPubKeyIndex2.equals(pubKeyIndex2)); } }); @@ -412,9 +411,8 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea } const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); - const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], 1) .mul(serverDKGPrivKeys[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) @@ -447,10 +445,9 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea // for imported key const { tssShare: retrievedTSS1, tssIndex: retrievedTSSIndex1 } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: "imported", }); - const tssCommits1 = tb.getTSSCommits(TSS_KEY_TYPE, "imported"); + const tssCommits1 = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey1 = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex1], 1) .mul(serverDKGPrivKeys1[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex1], retrievedTSSIndex1).mul(retrievedTSS1)) @@ -466,7 +463,6 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, - tssTag: "imported", }); equal(seed.equals(importedKey), true); } @@ -482,18 +478,17 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea if (tb2.secp256k1Key.cmp(reconstructedKey2.secp256k1Key) !== 0) { fail("key should be able to be reconstructed"); } - const tssCommits2 = tb2.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits2 = tb2.getTSSCommits(TSS_KEY_TYPE); const tssCommits20 = tssCommits2[0].toEllipticPoint(ecTSS); equal(tssPubKey.eq(tssCommits20), true); // switch to imported account - // tb2.tssTag = "imported"; + tb2.setTssTag("imported"); const { tssShare: retrievedTSSImported, tssIndex: retrievedTSSIndexImported } = await tb2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: "imported", }); - const tssCommitsImported = tb2.getTSSCommits(TSS_KEY_TYPE, "imported"); + const tssCommitsImported = tb2.getTSSCommits(TSS_KEY_TYPE); const tssPrivKeyImported = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndexImported], 1) .mul(serverDKGPrivKeys1[0]) @@ -566,9 +561,8 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea } const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); - const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], 1) .mul(serverDKGPrivKeys[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) @@ -601,14 +595,14 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea // for imported key { - const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE, "imported")[0].toEllipticPoint(ecTSS); + tb.setTssTag("imported"); + const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: "imported", }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(importedScalar); @@ -620,22 +614,20 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea factorKey, selectedServers: [3, 4, 5], authSignatures: signatures, - tssTag: "imported", }); equal(seed.equals(importedKey), true); } } { - // tb.tssTag = "default"; + tb.setTssTag(TSS_TAG_DEFAULT); - const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT)[0].toEllipticPoint(ecTSS); + const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -650,15 +642,14 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea await tb2.reconstructKey(); { - // tb2.tssTag = "imported"; - const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE, "imported")[0].toEllipticPoint(ecTSS); + tb2.setTssTag("imported"); + const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb2._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: "imported", }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -668,14 +659,13 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea { // tb2.tssTag = "default"; - const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT)[0].toEllipticPoint(ecTSS); + const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb2._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -742,7 +732,6 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea existingFactorKey: factorKey, newFactorPub: Point.fromElliptic(newFactorPub), newTSSIndex: deviceTSSIndex, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); @@ -756,7 +745,6 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea newFactorPub: Point.fromElliptic(newFactorPub), newTSSIndex, refreshShares: true, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); @@ -767,13 +755,12 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea factorKey, deleteFactorPub: Point.fromElliptic(newFactorPub), authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); it("should no longer be able to access key share with removed factor (same index)", async function () { - await rejects(tb.getTSSShare(newFactorKeySameIndex, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT })); + await rejects(tb.getTSSShare(newFactorKeySameIndex, { keyType: TSS_KEY_TYPE })); }); it("should be able to remove factor for different index", async function () { @@ -782,13 +769,12 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea factorKey, deleteFactorPub: Point.fromElliptic(newFactorPub), authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); it("should no longer be able to access key share with removed factor (different index)", async function () { - await rejects(tb.getTSSShare(newFactorKeyNewIndex, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT })); + await rejects(tb.getTSSShare(newFactorKeyNewIndex, { keyType: TSS_KEY_TYPE })); }); }); @@ -861,7 +847,7 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea await tbJson.reconstructKey(); // try refresh share - await tbJson.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); const newFactorKeyPair = ecFactor.genKeyPair(); await tbJson.addFactorPub({ @@ -870,10 +856,9 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea newFactorPub: Point.fromElliptic(newFactorKeyPair.getPublic()), newTSSIndex, refreshShares: true, - tssTag: TSS_TAG_DEFAULT, }); - await tbJson.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE }); const serialized2 = JSON.stringify(tbJson); @@ -885,8 +870,8 @@ const multiCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boolea await tbJson2.reconstructKey(); - await tbJson2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); - await tbJson2.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); + await tbJson2.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE }); }); }); }); diff --git a/packages/tss/test/tssSingleCurveTestCases.ts b/packages/tss/test/tssSingleCurveTestCases.ts index d52e157d..f87e9fa1 100644 --- a/packages/tss/test/tssSingleCurveTestCases.ts +++ b/packages/tss/test/tssSingleCurveTestCases.ts @@ -84,13 +84,13 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole if (tb1.secp256k1Key.cmp(reconstructedKey.secp256k1Key) !== 0) { fail("key should be able to be reconstructed"); } - const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); // compute public key of the tss share const tss2Pub = ecTSS.g.mul(tss2); // get tss pub key from tss commits - const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE); const tssCommitA0 = tssCommits[0].toEllipticPoint(ecTSS); const tssCommitA1 = tssCommits[1].toEllipticPoint(ecTSS); @@ -145,8 +145,8 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole fail("key should be able to be reconstructed"); } - const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); - const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const { tssShare: tss2 } = await tb1.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); + const tssCommits = tb1.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], 1) .mul(tss1) @@ -155,7 +155,7 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole const tssPubKey = (ecTSS.g as EllipticPoint).mul(tssPrivKey); const tssCommits0 = tssCommits[0].toEllipticPoint(ecTSS); - const tssPub = tb1.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT).toEllipticPoint(ecTSS); + const tssPub = tb1.getTSSPub(TSS_KEY_TYPE).toEllipticPoint(ecTSS); equal(tssPubKey.eq(tssCommits0), true); equal(tssPub.eq(tssPubKey), true); @@ -167,14 +167,14 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole const nonce = tb1.computeAccountNonce(accountIndex); return share.add(nonce).umod(ecTSS.n); })(); - const { tssShare: tss2Account } = await tb1.getTSSShare(factorKey, { accountIndex, keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + const { tssShare: tss2Account } = await tb1.getTSSShare(factorKey, { accountIndex, keyType: TSS_KEY_TYPE }); const coefficient1 = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], 1); const coefficient2 = getLagrangeCoeffs(ecTSS, [1, deviceTSSIndex], deviceTSSIndex); const tssKey = coefficient1.mul(tss1Account).add(coefficient2.mul(tss2Account)).umod(ecTSS.n); const tssKeyPub = (ecTSS.g as EllipticPoint).mul(tssKey); - const tssPubAccount = tb1.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT, accountIndex).toEllipticPoint(ecTSS); + const tssPubAccount = tb1.getTSSPub(TSS_KEY_TYPE, accountIndex).toEllipticPoint(ecTSS); equal(tssPubAccount.eq(tssKeyPub), true, "should equal account pub key"); } }); @@ -224,7 +224,7 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole // Check pub key. const ec = getEcCurve(TSS_KEY_TYPE); const importTssKeyPub = Point.fromScalar(importTssKey.scalar, ec); - const tssPub = await tb.getTSSPub(TSS_KEY_TYPE, "imported"); + const tssPub = await tb.getTSSPub(TSS_KEY_TYPE); assert(tssPub.equals(importTssKeyPub)); // Check exported key. @@ -232,14 +232,12 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole factorKey, authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); assert(exportedKey.eq(importTssKey.scalar)); if (TSS_KEY_TYPE === KeyType.ed25519) { const seed = await tb._UNSAFE_exportTssEd25519Seed({ factorKey, authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); assert(seed.equals(importTssKey.raw)); } else { @@ -249,10 +247,9 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole authSignatures: signatures, accountIndex: 2, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const exportedPubKeyIndex2 = Point.fromScalar(exportedKeyIndex2, ec); - const pubKeyIndex2 = tb.getTSSPub(TSS_KEY_TYPE, TSS_TAG_DEFAULT, 2); + const pubKeyIndex2 = tb.getTSSPub(TSS_KEY_TYPE, 2); assert(exportedPubKeyIndex2.equals(pubKeyIndex2)); } }); @@ -312,9 +309,8 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole } const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); - const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], 1) .mul(serverDKGPrivKeys[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) @@ -341,16 +337,16 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole } ); + // after import, tkey tss instance is on tssTag = "imported" // tag is switched to imported await tb.syncLocalMetadataTransitions(); // for imported key const { tssShare: retrievedTSS1, tssIndex: retrievedTSSIndex1 } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: "imported", }); - const tssCommits1 = tb.getTSSCommits(TSS_KEY_TYPE, "imported"); + const tssCommits1 = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey1 = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex1], 1) .mul(serverDKGPrivKeys1[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex1], retrievedTSSIndex1).mul(retrievedTSS1)) @@ -366,7 +362,6 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, - tssTag: "imported", }); equal(seed.equals(importedKey), true); } @@ -382,18 +377,17 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole if (tb2.secp256k1Key.cmp(reconstructedKey2.secp256k1Key) !== 0) { fail("key should be able to be reconstructed"); } - const tssCommits2 = tb2.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits2 = tb2.getTSSCommits(TSS_KEY_TYPE); const tssCommits20 = tssCommits2[0].toEllipticPoint(ecTSS); equal(tssPubKey.eq(tssCommits20), true); // switch to imported account - // tb2.tssTag = "imported"; + tb2.setTssTag("imported"); const { tssShare: retrievedTSSImported, tssIndex: retrievedTSSIndexImported } = await tb2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: "imported", }); - const tssCommitsImported = tb2.getTSSCommits(TSS_KEY_TYPE, "imported"); + const tssCommitsImported = tb2.getTSSCommits(TSS_KEY_TYPE); const tssPrivKeyImported = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndexImported], 1) .mul(serverDKGPrivKeys1[0]) @@ -448,9 +442,8 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole } const { tssShare: retrievedTSS, tssIndex: retrievedTSSIndex } = await tb.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); - const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT); + const tssCommits = tb.getTSSCommits(TSS_KEY_TYPE); const tssPrivKey = getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], 1) .mul(serverDKGPrivKeys[0]) .add(getLagrangeCoeffs(ecTSS, [1, retrievedTSSIndex], retrievedTSSIndex).mul(retrievedTSS)) @@ -492,14 +485,13 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole await tb.syncLocalMetadataTransitions(); // for imported key { - const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE, "imported")[0].toEllipticPoint(ecTSS); + const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: "imported", }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(importedScalar); @@ -511,22 +503,21 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole factorKey, selectedServers: [3, 4, 5], authSignatures: signatures, - tssTag: "imported", }); equal(seed.equals(importedKey), true); } } { // tb.tssTag = "default"; + tb.setTssTag(TSS_TAG_DEFAULT); - const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT)[0].toEllipticPoint(ecTSS); + const finalPubKey = tb.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -542,14 +533,14 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole await tb2.syncLocalMetadataTransitions(); { // tb2.tssTag = "imported"; - const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE, "imported")[0].toEllipticPoint(ecTSS); + tb2.setTssTag("imported"); + const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb2._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: "imported", }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -558,15 +549,15 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole } { // tb2.tssTag = "default"; + tb2.setTssTag(TSS_TAG_DEFAULT); - const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE, TSS_TAG_DEFAULT)[0].toEllipticPoint(ecTSS); + const finalPubKey = tb2.getTSSCommits(TSS_KEY_TYPE)[0].toEllipticPoint(ecTSS); const finalTssKey = await tb2._UNSAFE_exportTssKey({ factorKey, selectedServers: [1, 2, 3], authSignatures: signatures, keyType: TSS_KEY_TYPE, - tssTag: TSS_TAG_DEFAULT, }); const tssPubKeyImported = (ecTSS.g as EllipticPoint).mul(finalTssKey); @@ -633,7 +624,6 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole existingFactorKey: factorKey, newFactorPub: Point.fromElliptic(newFactorPub), newTSSIndex: deviceTSSIndex, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); @@ -647,7 +637,6 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole newFactorPub: Point.fromElliptic(newFactorPub), newTSSIndex, refreshShares: true, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); @@ -658,13 +647,12 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole factorKey, deleteFactorPub: Point.fromElliptic(newFactorPub), authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); it("should no longer be able to access key share with removed factor (same index)", async function () { - await rejects(tb.getTSSShare(newFactorKeySameIndex, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT })); + await rejects(tb.getTSSShare(newFactorKeySameIndex, { keyType: TSS_KEY_TYPE })); }); it("should be able to remove factor for different index", async function () { @@ -673,13 +661,12 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole factorKey, deleteFactorPub: Point.fromElliptic(newFactorPub), authSignatures: signatures, - tssTag: TSS_TAG_DEFAULT, }); await tb.syncLocalMetadataTransitions(); }); it("should no longer be able to access key share with removed factor (different index)", async function () { - await rejects(tb.getTSSShare(newFactorKeyNewIndex, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT })); + await rejects(tb.getTSSShare(newFactorKeyNewIndex, { keyType: TSS_KEY_TYPE })); }); }); @@ -752,7 +739,7 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole await tbJson.reconstructKey(); // try refresh share - await tbJson.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); const newFactorKeyPair = ecFactor.genKeyPair(); await tbJson.addFactorPub({ @@ -761,10 +748,9 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole newFactorPub: Point.fromElliptic(newFactorKeyPair.getPublic()), newTSSIndex, refreshShares: true, - tssTag: TSS_TAG_DEFAULT, }); - await tbJson.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE }); const serialized2 = JSON.stringify(tbJson); @@ -776,8 +762,8 @@ const singleCurveTestCases = (params: { TSS_KEY_TYPE: KeyType; legacyFlag: boole await tbJson2.reconstructKey(); - await tbJson2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); - await tbJson2.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE, tssTag: TSS_TAG_DEFAULT }); + await tbJson2.getTSSShare(factorKey, { keyType: TSS_KEY_TYPE }); + await tbJson2.getTSSShare(newFactorKeyPair.getPrivate(), { keyType: TSS_KEY_TYPE }); }); }); }); From 057f7949a90d25ebcfaf3a70c528b9106d8df5da Mon Sep 17 00:00:00 2001 From: ieow Date: Wed, 26 Feb 2025 04:21:14 +0800 Subject: [PATCH 2/3] fix: rebase issue --- packages/tss/src/tss.ts | 223 ++++++++++++++++++++-------------------- 1 file changed, 112 insertions(+), 111 deletions(-) diff --git a/packages/tss/src/tss.ts b/packages/tss/src/tss.ts index da0d963f..2c764df2 100644 --- a/packages/tss/src/tss.ts +++ b/packages/tss/src/tss.ts @@ -99,13 +99,9 @@ export class TKeyTSS extends TKey { this.legacyMetadataFlag = legacyMetadataFlag; } - // public get tssKeyType(): KeyType { - // return this._tssKeyType; - // } - - // public get tssCurve(): EllipticCurve { - // return this._tssCurve; - // } + public get tssTag(): string { + return this._tssTag; + } static async fromJSON(value: StringifiedType, args: TSSTKeyArgs): Promise { // legacyMetadataFlag need to be provided during constructor as tkey's fromJson is depending on the flag @@ -533,121 +529,126 @@ export class TKeyTSS extends TKey { this._tssTag = tssTag; const localTssTag = this._tssTag; - const tssData = this.metadata.getTssData(params.tssKeyType, localTssTag); - if (tssData) { - throw CoreError.default("Duplicate account tag, please use a unique tag for importing key"); - } + try { + const tssData = this.metadata.getTssData(params.tssKeyType, localTssTag); + if (tssData) { + throw CoreError.default("Duplicate account tag, please use a unique tag for importing key"); + } - const ec = getKeyCurve(tssKeyType); + const ec = getKeyCurve(tssKeyType); - const { selectedServers = [], authSignatures = [] } = serverOpts || {}; - - if (!localTssTag) throw CoreError.default(`invalid param, tag is required`); - if (!factorPubs || factorPubs.length === 0) throw CoreError.default(`invalid param, newFactorPub is required`); - if (!newTSSIndexes || newTSSIndexes.length === 0) throw CoreError.default(`invalid param, newTSSIndex is required`); - if (authSignatures.length === 0) throw CoreError.default(`invalid param, authSignatures is required`); - - const importScalar = await (async () => { - if (tssKeyType === KeyType.secp256k1) { - return new BN(importKey); - } else if (tssKeyType === KeyType.ed25519) { - // Store seed in metadata. - const domainKey = getEd25519SeedStoreDomainKey(localTssTag); - const result = this.metadata.getGeneralStoreDomain(domainKey) as Record; - if (result) { - throw new Error("Seed already exists"); - } + const { selectedServers = [], authSignatures = [] } = serverOpts || {}; - const { scalar } = getEd25519KeyPairFromSeed(importKey); - const encKey = Buffer.from(getSecpKeyFromEd25519(scalar).point.encodeCompressed("hex"), "hex"); - const msg = await encrypt(encKey, importKey); - this.metadata.setGeneralStoreDomain(domainKey, { message: msg }); + if (!localTssTag) throw CoreError.default(`invalid param, tag is required`); + if (!factorPubs || factorPubs.length === 0) throw CoreError.default(`invalid param, newFactorPub is required`); + if (!newTSSIndexes || newTSSIndexes.length === 0) throw CoreError.default(`invalid param, newTSSIndex is required`); + if (authSignatures.length === 0) throw CoreError.default(`invalid param, authSignatures is required`); - return scalar; - } - throw new Error("Invalid key type"); - })(); + const importScalar = await (async () => { + if (tssKeyType === KeyType.secp256k1) { + return new BN(importKey); + } else if (tssKeyType === KeyType.ed25519) { + // Store seed in metadata. + const domainKey = getEd25519SeedStoreDomainKey(localTssTag); + const result = this.metadata.getGeneralStoreDomain(domainKey) as Record; + if (result) { + throw new Error("Seed already exists"); + } - if (!importScalar || importScalar.toString("hex") === "0") { - throw new Error("Invalid importedKey"); - } + const { scalar } = getEd25519KeyPairFromSeed(importKey); + const encKey = Buffer.from(getSecpKeyFromEd25519(scalar).point.encodeCompressed("hex"), "hex"); + const msg = await encrypt(encKey, importKey); + this.metadata.setGeneralStoreDomain(domainKey, { message: msg }); - const tssIndexes = newTSSIndexes; - const existingNonce = tssData?.tssNonce ?? 0; - const newTssNonce: number = existingNonce && existingNonce > 0 ? existingNonce + 1 : 0; - const verifierAndVerifierID = this.serviceProvider.getVerifierNameVerifierId(); - const label = `${verifierAndVerifierID}\u0015${localTssTag}\u0016${newTssNonce}`; - const tssPubKey = hexPoint(ec.g.mul(importScalar)); - const rssNodeDetails = await this._getRssNodeDetails(); - const { pubKey: newTSSServerPub, nodeIndexes } = await this.serviceProvider.getTSSPubKey(localTssTag, newTssNonce, tssKeyType); - let finalSelectedServers = selectedServers; + return scalar; + } + throw new Error("Invalid key type"); + })(); - if (nodeIndexes?.length > 0) { - if (selectedServers.length) { - finalSelectedServers = nodeIndexes.slice(0, Math.min(selectedServers.length, nodeIndexes.length)); - } else { - finalSelectedServers = nodeIndexes.slice(0, 3); + if (!importScalar || importScalar.toString("hex") === "0") { + throw new Error("Invalid importedKey"); } - } else if (selectedServers?.length === 0) { - finalSelectedServers = randomSelection( - new Array(rssNodeDetails.serverEndpoints.length).fill(null).map((_, i) => i + 1), - Math.ceil(rssNodeDetails.serverEndpoints.length / 2) - ); - } - const { serverEndpoints, serverPubKeys, serverThreshold } = rssNodeDetails; + const tssIndexes = newTSSIndexes; + const existingNonce = tssData?.tssNonce ?? 0; + const newTssNonce: number = existingNonce && existingNonce > 0 ? existingNonce + 1 : 0; + const verifierAndVerifierID = this.serviceProvider.getVerifierNameVerifierId(); + const label = `${verifierAndVerifierID}\u0015${localTssTag}\u0016${newTssNonce}`; + const tssPubKey = hexPoint(ec.g.mul(importScalar)); + const rssNodeDetails = await this._getRssNodeDetails(); + const { pubKey: newTSSServerPub, nodeIndexes } = await this.serviceProvider.getTSSPubKey(localTssTag, newTssNonce, tssKeyType); + let finalSelectedServers = selectedServers; + + if (nodeIndexes?.length > 0) { + if (selectedServers.length) { + finalSelectedServers = nodeIndexes.slice(0, Math.min(selectedServers.length, nodeIndexes.length)); + } else { + finalSelectedServers = nodeIndexes.slice(0, 3); + } + } else if (selectedServers?.length === 0) { + finalSelectedServers = randomSelection( + new Array(rssNodeDetails.serverEndpoints.length).fill(null).map((_, i) => i + 1), + Math.ceil(rssNodeDetails.serverEndpoints.length / 2) + ); + } - const rssClient = new RSSClient({ - serverEndpoints, - serverPubKeys, - serverThreshold, - tssPubKey, - keyType: tssKeyType, - }); + const { serverEndpoints, serverPubKeys, serverThreshold } = rssNodeDetails; - const refreshResponses = await rssClient.import({ - importKey: importScalar, - dkgNewPub: pointToHex(newTSSServerPub), - selectedServers: finalSelectedServers, - factorPubs: factorPubs.map((f) => pointToHex(f)), - targetIndexes: tssIndexes, - newLabel: label, - sigs: authSignatures, - }); - const secondCommit = newTSSServerPub.toEllipticPoint(ec).add(ecPoint(ec, tssPubKey).neg()); - const newTSSCommits = [ - Point.fromJSON(tssPubKey), - Point.fromJSON({ x: secondCommit.getX().toString(16, 64), y: secondCommit.getY().toString(16, 64) }), - ]; - const factorEncs: { - [factorPubID: string]: FactorEnc; - } = {}; - for (let i = 0; i < refreshResponses.length; i++) { - const refreshResponse = refreshResponses[i]; - factorEncs[refreshResponse.factorPub.x.padStart(64, "0")] = { - type: "hierarchical", - tssIndex: refreshResponse.targetIndex, - userEnc: refreshResponse.userFactorEnc, - serverEncs: refreshResponse.serverFactorEncs, - }; - } - this.metadata.updateTSSData({ - tssKeyType, - tssTag: localTssTag, - tssNonce: newTssNonce, - tssPolyCommits: newTSSCommits, - factorPubs, - factorEncs, - }); - if (!this._accountSalt) { - const accountSalt = generateSalt(getKeyCurve(tssKeyType)); - await this._setTKeyStoreItem(TSS_MODULE, { - id: "accountSalt", - value: accountSalt, - } as IAccountSaltStore); - this._accountSalt = accountSalt; + const rssClient = new RSSClient({ + serverEndpoints, + serverPubKeys, + serverThreshold, + tssPubKey, + keyType: tssKeyType, + }); + + const refreshResponses = await rssClient.import({ + importKey: importScalar, + dkgNewPub: pointToHex(newTSSServerPub), + selectedServers: finalSelectedServers, + factorPubs: factorPubs.map((f) => pointToHex(f)), + targetIndexes: tssIndexes, + newLabel: label, + sigs: authSignatures, + }); + const secondCommit = newTSSServerPub.toEllipticPoint(ec).add(ecPoint(ec, tssPubKey).neg()); + const newTSSCommits = [ + Point.fromJSON(tssPubKey), + Point.fromJSON({ x: secondCommit.getX().toString(16, 64), y: secondCommit.getY().toString(16, 64) }), + ]; + const factorEncs: { + [factorPubID: string]: FactorEnc; + } = {}; + for (let i = 0; i < refreshResponses.length; i++) { + const refreshResponse = refreshResponses[i]; + factorEncs[refreshResponse.factorPub.x.padStart(64, "0")] = { + type: "hierarchical", + tssIndex: refreshResponse.targetIndex, + userEnc: refreshResponse.userFactorEnc, + serverEncs: refreshResponse.serverFactorEncs, + }; + } + this.metadata.updateTSSData({ + tssKeyType, + tssTag: localTssTag, + tssNonce: newTssNonce, + tssPolyCommits: newTSSCommits, + factorPubs, + factorEncs, + }); + if (!this._accountSalt) { + const accountSalt = generateSalt(getKeyCurve(tssKeyType)); + await this._setTKeyStoreItem(TSS_MODULE, { + id: "accountSalt", + value: accountSalt, + } as IAccountSaltStore); + this._accountSalt = accountSalt; + } + await this._syncShareMetadata(); + } catch (error) { + this._tssTag = oldTag; + throw error; } - await this._syncShareMetadata(); } /** @@ -851,7 +852,7 @@ export class TKeyTSS extends TKey { tssIndices: updatedTSSIndexes, remoteClient, keyType, - tssTag, + tssTag: this.tssTag, }); } From e4f22fb568d2cf08aab1def407a767b797ebcb91 Mon Sep 17 00:00:00 2001 From: ieow Date: Wed, 26 Feb 2025 04:23:22 +0800 Subject: [PATCH 3/3] fix: clean up --- packages/core/src/metadata.ts | 17 +++++++++-------- packages/tss/src/tss.ts | 15 ++------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/packages/core/src/metadata.ts b/packages/core/src/metadata.ts index 72cbfdf4..330a2b1f 100644 --- a/packages/core/src/metadata.ts +++ b/packages/core/src/metadata.ts @@ -31,7 +31,6 @@ import { TssMetadata } from "./tssMetadata"; export const LEGACY_METADATA_VERSION = "0.0.1"; export const METADATA_VERSION = "1.0.0"; - export class Metadata implements IMetadata { pubKey: Point; @@ -58,7 +57,7 @@ export class Metadata implements IMetadata { tss?: { [tssTag: string]: { - [curveType: string]: TssMetadata; + [curveType in KeyType]?: TssMetadata; }; }; @@ -105,19 +104,23 @@ export class Metadata implements IMetadata { if (version === METADATA_VERSION) { metadata.tss = {}; - if (tss) { + if (tss instanceof Object) { Object.keys(tss).forEach((tsstag) => { - if (tss[tsstag]) { + if (tss[tsstag] instanceof Object) { metadata.tss[tsstag] = {}; Object.keys(tss[tsstag]).forEach((tssKeyType) => { - metadata.tss[tsstag][tssKeyType] = TssMetadata.fromJSON(tss[tsstag][tssKeyType]); + if (tssKeyType in KeyType) { + metadata.tss[tsstag][tssKeyType as KeyType] = TssMetadata.fromJSON(tss[tsstag][tssKeyType]); + } else { + throw new Error(`tssKeyType not supported ${tssKeyType}`); + } }); } }); } // else would be legacy version, migrate for secp version - } else if (factorEncs) { + } else if (factorEncs instanceof Object) { metadata.tss = {}; // some tests case on backward compatbility tests having serialized metadata with empty tssKeyTypes const tssKeyTypes: Record = tssKeyTypesJson ?? {}; @@ -534,8 +537,6 @@ export class LegacyMetadata extends Metadata { tssPolyCommits, factorPubs, factorEncs, - // Legacy Metadata version - // version: this.version, }; } diff --git a/packages/tss/src/tss.ts b/packages/tss/src/tss.ts index 2c764df2..ff54e61d 100644 --- a/packages/tss/src/tss.ts +++ b/packages/tss/src/tss.ts @@ -50,7 +50,6 @@ export const LEGACY_KEY_TYPE = "secp256k1"; export interface TSSTKeyArgs extends TKeyArgs { serviceProvider: TSSTorusServiceProvider; - // tssKeyType: KeyType; tssTag?: string; legacyMetadataFlag?: boolean; } @@ -70,10 +69,6 @@ export interface TKeyTSSInitArgs { export class TKeyTSS extends TKey { serviceProvider: TSSTorusServiceProvider = null; - // private _tssKeyType: KeyType; - - // private _tssCurve: EC; - private _tssTag: string; private _accountSalt: string; @@ -94,8 +89,6 @@ export class TKeyTSS extends TKey { this.serviceProvider = serviceProvider; this.storageLayer = storageLayer; this._tssTag = tssTag; - // this._tssKeyType = tssKeyType; - // this._tssCurve = new EC(tssKeyType); this.legacyMetadataFlag = legacyMetadataFlag; } @@ -114,10 +107,6 @@ export class TKeyTSS extends TKey { throw CoreError.default(`tssTag mismatch: ${tssTag} !== ${tbTss._tssTag}`); } - // if (tssKeyType !== tbTss.tssKeyType) { - // throw CoreError.default(`tssKeyType mismatch: ${tssKeyType} !== ${tbTss.tssKeyType}`); - // } - // copy over tkey to tkeyTss tbTss.shares = tb.shares; tbTss.metadata = tb.metadata; @@ -526,7 +515,7 @@ export class TKeyTSS extends TKey { const oldTag = this._tssTag; // update current tssTag - this._tssTag = tssTag; + this.setTssTag(tssTag); const localTssTag = this._tssTag; try { @@ -646,7 +635,7 @@ export class TKeyTSS extends TKey { } await this._syncShareMetadata(); } catch (error) { - this._tssTag = oldTag; + this.setTssTag(oldTag); throw error; } }