From 9556451607828331c07f65029feb4129b2ba3294 Mon Sep 17 00:00:00 2001 From: ieow Date: Tue, 17 Dec 2024 14:25:28 +0800 Subject: [PATCH] feat: update interface --- src/interfaces.ts | 63 +++--------------------------------- src/mpcCoreKit.ts | 47 +++++++++++++++++++-------- src/plugins/IRemoteSigner.ts | 62 +++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 72 deletions(-) create mode 100644 src/plugins/IRemoteSigner.ts diff --git a/src/interfaces.ts b/src/interfaces.ts index 5467b2c..6d4bae6 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,4 +1,4 @@ -import { BNString, FactorEnc, KeyType, Point as TkeyPoint, ShareDescriptionMap } from "@tkey/common-types"; +import { BNString, KeyType, Point as TkeyPoint, ShareDescriptionMap } from "@tkey/common-types"; import { IRemoteClientState, TKeyTSS, TSSTorusServiceProvider } from "@tkey/tss"; import { WEB3AUTH_SIG_TYPE } from "@toruslabs/constants"; import type { @@ -13,7 +13,7 @@ import type { UX_MODE_TYPE, } from "@toruslabs/customauth"; import { TorusKey } from "@toruslabs/torus.js"; -import { Client, PointHex } from "@toruslabs/tss-client"; +import { Client } from "@toruslabs/tss-client"; // TODO: move the types to a base class for both dkls and frost in future import type { tssLib as TssDklsLib } from "@toruslabs/tss-dkls-lib"; import type { tssLib as TssFrostLibEd25519 } from "@toruslabs/tss-frost-lib"; @@ -22,6 +22,7 @@ import { SafeEventEmitter } from "@web3auth/auth"; import BN from "bn.js"; import { FactorKeyTypeShareDescription, TssShareType, USER_PATH, WEB3AUTH_NETWORK } from "./constants"; +import { IRemoteSignerContext } from "./plugins/IRemoteSigner"; import { ISessionSigGenerator } from "./plugins/ISessionSigGenerator"; export type CoreKitMode = UX_MODE_TYPE | "nodejs" | "react-native"; @@ -337,7 +338,7 @@ export interface Web3AuthOptions { } export type Web3AuthOptionsWithDefaults = Required; -export interface IMPCContext { +export interface IMPCContext extends IRemoteSignerContext { stateEmitter: SafeEventEmitter; config: Web3AuthOptionsWithDefaults; status: COREKIT_STATUS; @@ -527,59 +528,3 @@ export interface Secp256k1PrecomputedClient { export type StateEmitterEvents = { LOGOUT: () => void; }; - -type SupportedCurve = "secp256k1" | "ed25519"; -// remote signer interface -export type RemoteDklsSignParams = { - factorEnc?: FactorEnc; - sessionId: string; - tssNonce: number; - accountNonce: string; - tssPubKeyHex: string; - - nodeIndexes: number[]; - tssCommits: PointHex[]; - - signatures: string[]; - - serverEndpoints: { - endpoints: string[]; - tssWSEndpoints: string[]; - partyIndexes: number[]; - }; - - curve: SupportedCurve; -}; - -export type ICustomFrostSignParams = { - sessionId: string; - signatures: string[]; - tssCommits: PointHex[]; - factorEnc: FactorEnc; - tssPubKeyHex: string; - curve: SupportedCurve; - - serverXCoords: number[]; - clientXCoord: number; - serverCoefficients: string[]; - clientCoefficient: string; - serverURLs: string[]; -}; - -export interface ICustomDklsSignParams { - sessionId: string; - signatures: string[]; - tssCommits: PointHex[]; - factorEnc: FactorEnc; - tssPubKeyHex: string; - curve: SupportedCurve; - - participatingServerDKGIndexes: number[]; - clientIndex: number; - tssNonce: string; - accountNonce: string; - - endpoints: string[]; - tssWSEndpoints: string[]; - partyIndexes: number[]; -} diff --git a/src/mpcCoreKit.ts b/src/mpcCoreKit.ts index 0d6c2b0..6cbf793 100644 --- a/src/mpcCoreKit.ts +++ b/src/mpcCoreKit.ts @@ -49,8 +49,6 @@ import { CreateFactorParams, EnableMFAParams, ICoreKit, - ICustomDklsSignParams, - ICustomFrostSignParams, IFactorKey, IMPCContext, InitParams, @@ -71,6 +69,7 @@ import { Web3AuthState, } from "./interfaces"; import { DefaultSessionSigGeneratorPlugin } from "./plugins/DefaultSessionSigGenerator"; +import { ICustomDklsSignParams, ICustomFrostSignParams } from "./plugins/IRemoteSigner"; import { ISessionSigGenerator } from "./plugins/ISessionSigGenerator"; import { deriveShareCoefficients, @@ -732,6 +731,20 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { return ed25519().keyFromPublic(p).getPublic(); } + /** + * Get public key in bip340 format. + * + * Throws an error if signature type is not bip340. + */ + public getPubKeyBip340(): Buffer { + if (this._sigType !== "bip340") { + throw CoreKitError.default(`getPubKeyBip340 not supported for signature type ${this.sigType}`); + } + + const p = this.tkey.tssCurve.keyFromPublic(this.getPubKey()).getPublic(); + return p.getX().toBuffer("be", 32); + } + public async preSetupSigning(): Promise { const { torusNodeTSSEndpoints } = fetchLocalConfig(this.options.web3AuthNetwork, this.keyType); @@ -742,7 +755,6 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { } const tssNonce = this.getTssNonce() || 0; - const vid = `${this.verifier}${DELIMITERS.Delimiter1}${this.verifierId}`; const sessionId = `${vid}${DELIMITERS.Delimiter2}default${DELIMITERS.Delimiter3}${tssNonce}${DELIMITERS.Delimiter4}`; @@ -764,7 +776,9 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { nodeIndexesReturned: participatingServerDKGIndexes, } = generateTSSEndpoints(torusNodeTSSEndpoints, parties, clientIndex, nodeIndexes); - const factor = Point.fromSEC1(secp256k1, this.state.remoteClient?.remoteFactorPub); + const factor = this.state.remoteClient?.remoteFactorPub + ? Point.fromSEC1(secp256k1, this.state.remoteClient?.remoteFactorPub) + : Point.fromScalar(this.state.factorKey, secp256k1); const factorEnc = this.tKey.getFactorEncs(factor); // Compute account nonce only supported for secp256k1 @@ -1061,6 +1075,18 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { async setupRemoteSigning(params: IRemoteClientState, rehydrate: boolean = false): Promise { const { remoteFactorPub, metadataShare } = params; + + // rehydrate session + if (rehydrate) { + this.updateState({ remoteClient: params }); + const sessionResult = await this.sessionManager.authorizeSession().catch(async (err) => { + log.error("rehydrate session error", err); + }); + if (sessionResult) { + await this.rehydrateSession(sessionResult); + } + } + const details = this.getKeyDetails().shareDescriptions[remoteFactorPub]; if (!details) throw CoreKitError.default("factor description not found"); @@ -1198,7 +1224,6 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { tssPubKey: Buffer.from(tssPubKey).toString("hex"), signatures: await this.getSessionSignatures(), userInfo, - remoteClientState: this.state.remoteClient, }; await this.sessionManager.createSession(payload); // to accommodate async storage @@ -1337,7 +1362,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { } const factorKey = new BN(result.factorKey, "hex"); - if (!factorKey && !result.remoteClientState?.metadataShare) { + if (!result.factorKey && !this.state.remoteClient.metadataShare) { throw CoreKitError.providedFactorKeyInvalid(); } @@ -1347,13 +1372,10 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { await this.tKey.initialize({ neverInitializeNewKey: true }); - // skip input share store if factor key is not present - // tkey will be at state initalized - if (!result.factorKey) { - return; - } + const metadataShareStore = this.state.remoteClient?.metadataShare + ? ShareStore.fromJSON(JSON.parse(this.state.remoteClient.metadataShare)) + : await this.getFactorKeyMetadata(factorKey); - const metadataShareStore = await this.getFactorKeyMetadata(factorKey); await this.tKey.inputShareStoreSafe(metadataShareStore, true); await this.tKey.reconstructKey(); @@ -1365,7 +1387,6 @@ export class Web3AuthMPCCoreKit implements ICoreKit, IMPCContext { tssPubKey: this.tkey.getTSSPub().toSEC1(this.tKey.tssCurve, false), signatures: result.signatures, userInfo: result.userInfo, - remoteClient: result.remoteClientState, }); } catch (err) { log.warn("failed to authorize session", err); diff --git a/src/plugins/IRemoteSigner.ts b/src/plugins/IRemoteSigner.ts new file mode 100644 index 0000000..33f3493 --- /dev/null +++ b/src/plugins/IRemoteSigner.ts @@ -0,0 +1,62 @@ +import { FactorEnc, Point, ShareDescriptionMap } from "@tkey/common-types"; +import { IRemoteClientState } from "@tkey/tss"; +import { PointHex } from "@toruslabs/tss-client"; + +import { CreateFactorParams, WEB3AUTH_NETWORK_TYPE } from "../interfaces"; + +type SupportedCurve = "secp256k1" | "ed25519"; + +export type ICustomFrostSignParams = { + sessionId: string; + signatures: string[]; + tssCommits: PointHex[]; + factorEnc: FactorEnc; + tssPubKeyHex: string; + curve: SupportedCurve; + + serverXCoords: number[]; + clientXCoord: number; + serverCoefficients: string[]; + clientCoefficient: string; + serverURLs: string[]; +}; + +export interface ICustomDklsSignParams { + sessionId: string; + signatures: string[]; + tssCommits: PointHex[]; + factorEnc: FactorEnc; + tssPubKeyHex: string; + curve: SupportedCurve; + + participatingServerDKGIndexes: number[]; + clientIndex: number; + tssNonce: string; + accountNonce: string; + + endpoints: string[]; + tssWSEndpoints: string[]; + partyIndexes: number[]; +} + +export interface ICustomDKLSSign { + sign: (params: ICustomDklsSignParams, msgHash: Uint8Array) => Promise<{ v: number; r: Uint8Array; s: Uint8Array }>; +} + +export interface ICustomFrostSign { + sign: (params: ICustomFrostSignParams, msgHash: Uint8Array) => Promise; +} +export interface IRemoteSignerContext { + setupRemoteSigning(params: Omit, rehydrate?: boolean): Promise; + createFactor(createFactorParams: CreateFactorParams): Promise; + inputFactorKey(factorKey: string): Promise; + deleteFactor(factorPub: Point, factorKey?: string): Promise; + getKeyDetails(): Record & { shareDescriptions: ShareDescriptionMap }; + getMetadataKey(): string | undefined; + getMetadataPublicKey(): string | undefined; + getWeb3AuthNetwork(): WEB3AUTH_NETWORK_TYPE; + + // Added new methods + setCustomDKLSSign(customDKLSSign: ICustomDKLSSign): void; + setCustomFrostSign(customDKLSSign: ICustomFrostSign): void; +}