@@ -2,7 +2,16 @@ import { BNString, KeyType, Point, secp256k1, SHARE_DELETED, ShareStore, Stringi
22import { CoreError } from "@tkey/core" ;
33import { ShareSerializationModule } from "@tkey/share-serialization" ;
44import { TorusStorageLayer } from "@tkey/storage-layer-torus" ;
5- import { DELIMITERS , factorKeyCurve , getPubKeyPoint , IRemoteClientState , lagrangeInterpolation , TKeyTSS , TSSTorusServiceProvider } from "@tkey/tss" ;
5+ import {
6+ DELIMITERS ,
7+ factorKeyCurve ,
8+ getPubKeyPoint ,
9+ IRemoteClientState ,
10+ lagrangeInterpolation ,
11+ pointToHex ,
12+ TKeyTSS ,
13+ TSSTorusServiceProvider ,
14+ } from "@tkey/tss" ;
615import { KEY_TYPE , SIGNER_MAP } from "@toruslabs/constants" ;
716import { AGGREGATE_VERIFIER , TORUS_METHOD , TorusAggregateLoginResponse , TorusLoginResponse , UX_MODE } from "@toruslabs/customauth" ;
817import type { UX_MODE_TYPE } from "@toruslabs/customauth/dist/types/utils/enums" ;
@@ -44,6 +53,8 @@ import {
4453 JWTLoginParams ,
4554 MPCKeyDetails ,
4655 OAuthLoginParams ,
56+ RemoteDklsSignParams ,
57+ RemoteFrostSignParams ,
4758 SessionData ,
4859 SubVerifierDetailsParams ,
4960 TkeyLocalStoreData ,
@@ -591,7 +602,9 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
591602 const { shareType } = createFactorParams ;
592603
593604 let { factorKey, shareDescription, additionalMetadata } = createFactorParams ;
594- factorKey = factorKey ? new BN ( factorKey , "hex" ) : undefined ;
605+ if ( typeof factorKey === "string" ) {
606+ factorKey = new BN ( factorKey , "hex" ) ;
607+ }
595608
596609 if ( ! VALID_SHARE_INDICES . includes ( shareType ) ) {
597610 throw CoreKitError . newShareIndexInvalid ( `Invalid share type provided (${ shareType } ). Valid share types are ${ VALID_SHARE_INDICES } .` ) ;
@@ -670,6 +683,9 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
670683 const sig = await this . sign_ECDSA_secp256k1 ( data , hashed ) ;
671684 return Buffer . concat ( [ sig . r , sig . s , Buffer . from ( [ sig . v ] ) ] ) ;
672685 } else if ( this . keyType === KeyType . ed25519 ) {
686+ if ( this . state . remoteClient ) {
687+ return this . remoteSignFrostEd25519 ( data , hashed ) ;
688+ }
673689 return this . sign_ed25519 ( data , hashed ) ;
674690 }
675691 throw CoreKitError . default ( `sign not supported for key type ${ this . keyType } ` ) ;
@@ -925,23 +941,27 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
925941 }
926942 const { endpoints, tssWSEndpoints, partyIndexes } = generateTSSEndpoints ( torusNodeTSSEndpoints , parties , clientIndex , nodeIndexes ) ;
927943
944+ const accountNonce = this . tkey . computeAccountNonce ( this . state . accountIndex ) ;
928945 const factor = Point . fromSEC1 ( secp256k1 , this . state . remoteClient . remoteFactorPub ) ;
929946 const factorEnc = this . tKey . getFactorEncs ( factor ) ;
930947
931- const data = {
932- dataRequired : {
948+ const data : { remoteSignParams : RemoteDklsSignParams ; msgHash : string } = {
949+ remoteSignParams : {
933950 factorEnc,
934951 sessionId,
935952 tssNonce,
953+ accountNonce : accountNonce . toString ( "hex" ) ,
936954 nodeIndexes : nodeIndexes . slice ( 0 , parties - 1 ) ,
937- tssCommits : tssCommits . map ( ( commit ) => commit . toJSON ( ) ) ,
955+ tssCommits : tssCommits . map ( ( commit ) => pointToHex ( commit ) ) ,
938956 signatures : this . signatures ,
939957 serverEndpoints : { endpoints, tssWSEndpoints, partyIndexes } ,
958+ tssPubKeyHex : this . state . tssPubKey . toString ( "hex" ) ,
959+ curve : this . tkey . tssKeyType ,
940960 } ,
941961 msgHash : msgData . toString ( "hex" ) ,
942962 } ;
943963
944- const result = await post < { data ?: Record < string , string > } > ( `${ this . state . remoteClient . remoteClientUrl } /api/v3/mpc/sign` , data , {
964+ const result = await post < { data ?: Record < string , string > } > ( `${ this . state . remoteClient . remoteClientUrl } /api/v3/mpc/sign/dkls ` , data , {
945965 headers : {
946966 Authorization : `Bearer ${ this . state . remoteClient . remoteClientToken } ` ,
947967 } ,
@@ -950,6 +970,76 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
950970 return { v : parseInt ( v ) , r : Buffer . from ( r , "hex" ) , s : Buffer . from ( s , "hex" ) } ;
951971 }
952972
973+ public async remoteSignFrostEd25519 ( data : Buffer , hashed : boolean = false ) : Promise < Buffer > {
974+ if ( hashed ) {
975+ throw CoreKitError . default ( "hashed data not supported for ed25519" ) ;
976+ }
977+
978+ const nodeDetails = fetchLocalConfig ( this . options . web3AuthNetwork , "ed25519" ) ;
979+ if ( ! nodeDetails . torusNodeTSSEndpoints ) {
980+ throw CoreKitError . default ( "could not fetch tss node endpoints" ) ;
981+ }
982+
983+ // Endpoints must end with backslash, but URLs returned by
984+ // `fetch-node-details` don't have it.
985+ const ED25519_ENDPOINTS = nodeDetails . torusNodeTSSEndpoints . map ( ( ep , i ) => ( { index : nodeDetails . torusIndexes [ i ] , url : `${ ep } /` } ) ) ;
986+
987+ // Select endpoints and derive party indices.
988+ const serverThreshold = Math . floor ( ED25519_ENDPOINTS . length / 2 ) + 1 ;
989+ const endpoints = sampleEndpoints ( ED25519_ENDPOINTS , serverThreshold ) ;
990+ const serverXCoords = endpoints . map ( ( x ) => x . index ) ;
991+ const clientXCoord = Math . max ( ...endpoints . map ( ( ep ) => ep . index ) ) + 1 ;
992+
993+ // Derive share coefficients for flat hierarchy.
994+ const ec = new Ed25519Curve ( ) ;
995+ const { serverCoefficients, clientCoefficient } = deriveShareCoefficients ( ec , serverXCoords , clientXCoord , this . state . tssShareIndex ) ;
996+
997+ // Get pub key.
998+ const tssPubKey = await this . getPubKey ( ) ;
999+ const tssPubKeyPoint = ec . keyFromPublic ( tssPubKey ) . getPublic ( ) ;
1000+
1001+ // Get client key share and adjust by coefficient.
1002+ if ( this . state . accountIndex !== 0 ) {
1003+ throw CoreKitError . default ( "Account index not supported for ed25519" ) ;
1004+ }
1005+
1006+ // Generate session identifier.
1007+ const tssNonce = this . getTssNonce ( ) ;
1008+ const sessionNonce = generateSessionNonce ( ) ;
1009+ const session = getSessionId ( this . verifier , this . verifierId , this . tKey . tssTag , tssNonce , sessionNonce ) ;
1010+
1011+ // Run signing protocol.
1012+
1013+ const serverURLs = endpoints . map ( ( x ) => x . url ) ;
1014+ const tssPubKeyHex = ec . pointToBuffer ( tssPubKeyPoint , Buffer ) . toString ( "hex" ) ;
1015+
1016+ const factorPub = Point . fromSEC1 ( secp256k1 , this . state . remoteClient . remoteFactorPub ) ;
1017+ const params : { remoteSignParams : RemoteFrostSignParams ; msgHash : string } = {
1018+ remoteSignParams : {
1019+ sessionId : session ,
1020+ signatures : this . signatures ,
1021+ tssCommits : this . tKey . getTSSCommits ( ) . map ( ( commit ) => pointToHex ( commit ) ) ,
1022+ factorEnc : this . tKey . getFactorEncs ( factorPub ) ,
1023+ serverXCoords,
1024+ clientXCoord,
1025+ serverCoefficients : serverCoefficients . map ( ( sc ) => sc . toString ( "hex" ) ) ,
1026+ clientCoefficient : clientCoefficient . toString ( "hex" ) ,
1027+ tssPubKeyHex,
1028+ serverURLs,
1029+ curve : this . tkey . tssKeyType ,
1030+ } ,
1031+ msgHash : data . toString ( "hex" ) ,
1032+ } ;
1033+
1034+ const result = await post < { data ?: Record < string , string > } > ( `${ this . state . remoteClient . remoteClientUrl } /api/v3/mpc/sign/frost` , params , {
1035+ headers : {
1036+ Authorization : `Bearer ${ this . state . remoteClient . remoteClientToken } ` ,
1037+ } ,
1038+ } ) ;
1039+
1040+ return Buffer . from ( result . data . signature , "hex" ) ;
1041+ }
1042+
9531043 public updateState ( newState : Partial < Web3AuthState > ) : void {
9541044 this . state = { ...this . state , ...newState } ;
9551045 }
@@ -966,6 +1056,8 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
9661056 }
9671057 }
9681058 return r ;
1059+ } catch ( e ) {
1060+ throw e as Error ;
9691061 } finally {
9701062 this . atomicCallStackCounter -= 1 ;
9711063 if ( this . atomicCallStackCounter === 0 ) {
0 commit comments