Skip to content

Commit f8ab2e1

Browse files
committed
fix: setDeviceFactor
1 parent ca544d3 commit f8ab2e1

File tree

6 files changed

+414
-32
lines changed

6 files changed

+414
-32
lines changed

src/mpcCoreKit.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
323323
if (this.isNodejsOrRN(this.options.uxMode)) {
324324
throw CoreKitError.oauthLoginUnsupported(`Oauth login is NOT supported in ${this.options.uxMode} mode.`);
325325
}
326+
327+
if ( this.state.factorKey ) {
328+
throw CoreKitError.oauthLoginUnsupported("Instance is alreay login or rehydrated");
329+
}
330+
326331
const { importTssKey, registerExistingSFAKey } = params;
327332
const tkeyServiceProvider = this.torusSp;
328333

@@ -677,7 +682,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
677682
*/
678683
public getPubKey(): Buffer {
679684
const { tssPubKey } = this.state;
680-
return Buffer.from(tssPubKey);
685+
return tssPubKey;
681686
}
682687

683688
/**
@@ -1107,6 +1112,7 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
11071112
shareDescription: FactorKeyTypeShareDescription.Other,
11081113
updateMetadata: false,
11091114
});
1115+
await this.setDeviceFactor(factorKey);
11101116
} else {
11111117
await this.addFactorDescription({
11121118
factorKey,
@@ -1199,6 +1205,14 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
11991205
signatures: result.signatures,
12001206
userInfo: result.userInfo,
12011207
});
1208+
1209+
// update device factor if not present upon rehydration
1210+
if (this.options.disableHashedFactorKey) {
1211+
const deviceFactorKey = await this.getDeviceFactor();
1212+
if (!deviceFactorKey && this.state.factorKey && this.state.tssShareIndex === TssShareType.DEVICE) {
1213+
await this.setDeviceFactor(this.state.factorKey);
1214+
}
1215+
}
12021216
} catch (err) {
12031217
log.warn("failed to authorize session", err);
12041218
}

tests/factors.spec.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import assert from "node:assert";
22
import test from "node:test";
33

4-
import { EllipticPoint, Point } from "@tkey/common-types";
4+
import { EllipticPoint, KeyType, Point, secp256k1 } from "@tkey/common-types";
55
import { factorKeyCurve } from "@tkey/tss";
66
import { tssLib as tssLibDKLS } from "@toruslabs/tss-dkls-lib";
77
import { tssLib as tssLibFROST } from "@toruslabs/tss-frost-lib";
88
import BN from "bn.js";
99

10-
import { COREKIT_STATUS, IAsyncStorage, IStorage, MemoryStorage, TssLibType, TssShareType, WEB3AUTH_NETWORK, Web3AuthMPCCoreKit } from "../src";
10+
import { AsyncStorage, COREKIT_STATUS, ed25519, IAsyncStorage, IStorage, MemoryStorage, sigToRSV, TssLibType, TssShareType, WEB3AUTH_NETWORK, Web3AuthMPCCoreKit } from "../src";
1111
import { AsyncMemoryStorage, bufferToElliptic, criticalResetAccount, mockLogin } from "./setup";
12+
import { keccak256 } from "@toruslabs/metadata-helpers";
1213

1314
type FactorTestVariable = {
1415
manualSync?: boolean;
@@ -28,6 +29,26 @@ function getPubKeys(kit: Web3AuthMPCCoreKit, indices: number[]): EllipticPoint[]
2829
return pubKeys;
2930
}
3031

32+
async function signSecp256k1Data( params : { coreKitInstance: Web3AuthMPCCoreKit, msg: string, }) {
33+
const {coreKitInstance, msg } = params
34+
const msgBuffer1 = Buffer.from(msg);
35+
const msgHash = keccak256(msgBuffer1);
36+
37+
const signature = sigToRSV(await coreKitInstance.sign(msgHash, true));
38+
39+
const pubkey = secp256k1.recoverPubKey(msgHash, signature, signature.v) as EllipticPoint;
40+
const publicKeyPoint = bufferToElliptic(coreKitInstance.getPubKey());
41+
assert(pubkey.eq(publicKeyPoint));
42+
}
43+
44+
async function signEd25519Data(params: { coreKitInstance: Web3AuthMPCCoreKit, msg: string }) {
45+
const { coreKitInstance, msg } = params;
46+
const msgBuffer = Buffer.from(msg)
47+
const signature = ed25519().makeSignature((await coreKitInstance.sign(msgBuffer)).toString("hex"));
48+
const valid = ed25519().verify(msgBuffer, signature, coreKitInstance.getPubKeyEd25519());
49+
assert(valid);
50+
}
51+
3152
export const FactorManipulationTest = async (testVariable: FactorTestVariable) => {
3253
const { email, tssLib } = testVariable;
3354
const newInstance = async () => {
@@ -39,6 +60,7 @@ export const FactorManipulationTest = async (testVariable: FactorTestVariable) =
3960
tssLib: tssLib || tssLibDKLS,
4061
storage: testVariable.storage,
4162
manualSync: testVariable.manualSync,
63+
disableSessionManager: true
4264
});
4365

4466
const { idToken, parsedToken } = await mockLogin(email);
@@ -55,6 +77,7 @@ export const FactorManipulationTest = async (testVariable: FactorTestVariable) =
5577
const resetInstance = await newInstance();
5678
await criticalResetAccount(resetInstance);
5779
await resetInstance.logout();
80+
await new AsyncStorage(resetInstance._storageKey, testVariable.storage).resetStore();
5881
}
5982

6083
await test(`#Factor manipulation - manualSync ${testVariable.manualSync} `, async function (t) {
@@ -163,6 +186,7 @@ export const FactorManipulationTest = async (testVariable: FactorTestVariable) =
163186
// login with mfa factor
164187
await instance2.inputFactorKey(new BN(recoverFactor, "hex"));
165188
assert.strictEqual(instance2.status, COREKIT_STATUS.LOGGED_IN);
189+
166190
await instance2.logout();
167191

168192
// new instance
@@ -180,16 +204,24 @@ export const FactorManipulationTest = async (testVariable: FactorTestVariable) =
180204

181205
await instance3.inputFactorKey(new BN(browserFactor, "hex"));
182206
assert.strictEqual(instance3.status, COREKIT_STATUS.LOGGED_IN);
207+
208+
if ( tssLib && tssLib.keyType === KeyType.ed25519) {
209+
await signEd25519Data({ coreKitInstance: instance3, msg: "hello world" });
210+
} else {
211+
await signSecp256k1Data({ coreKitInstance: instance3, msg: "hello world" });
212+
}
213+
183214
});
215+
184216
});
185217
};
186218

187219
const variable: FactorTestVariable[] = [
188-
{ manualSync: true, storage: new MemoryStorage(), email: "testmail1012" },
189-
{ manualSync: false, storage: new MemoryStorage(), email: "testmail1013" },
220+
{ manualSync: true, storage: new MemoryStorage(), email: "testmail1012-1" },
221+
{ manualSync: false, storage: new MemoryStorage(), email: "testmail1013-1" },
190222

191-
{ manualSync: true, storage: new AsyncMemoryStorage(), email: "testmail1014" },
192-
{ manualSync: false, storage: new AsyncMemoryStorage(), email: "testmail1015" },
223+
{ manualSync: true, storage: new AsyncMemoryStorage(), email: "testmail1014-1" },
224+
{ manualSync: false, storage: new AsyncMemoryStorage(), email: "testmail1015-1" },
193225

194226
{ manualSync: true, storage: new MemoryStorage(), email: "testmail1012ed25519", tssLib: tssLibFROST },
195227
];

tests/importRecovery.spec.ts

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,63 @@ import test from "node:test";
44
import { tssLib as tssLibDKLS } from "@toruslabs/tss-dkls-lib";
55
import { tssLib as tssLibFROST } from "@toruslabs/tss-frost-lib";
66

7-
import { AsyncStorage, MemoryStorage, TssLibType, TssShareType, WEB3AUTH_NETWORK } from "../src";
8-
import { bufferToElliptic, criticalResetAccount, newCoreKitLogInInstance } from "./setup";
7+
import { MemoryStorage, sigToRSV, TssLibType, TssShareType, WEB3AUTH_NETWORK, Web3AuthMPCCoreKit } from "../src";
8+
import { bufferToElliptic, criticalResetAccount, mockLogin } from "./setup";
9+
import { EllipticPoint, KeyType, secp256k1 } from "@tkey/common-types";
10+
import { keccak256 } from "@toruslabs/metadata-helpers";
911

1012
type ImportKeyTestVariable = {
1113
manualSync?: boolean;
1214
email: string;
1315
importKeyEmail: string;
1416
tssLib: TssLibType;
1517
};
18+
async function signSecp256k1Data( params : { coreKitInstance: Web3AuthMPCCoreKit, msg: string, }) {
19+
const {coreKitInstance, msg } = params
20+
const msgBuffer1 = Buffer.from(msg);
21+
const msgHash = keccak256(msgBuffer1);
1622

23+
const signature = sigToRSV(await coreKitInstance.sign(msgHash, true));
24+
25+
const pubkey = secp256k1.recoverPubKey(msgHash, signature, signature.v) as EllipticPoint;
26+
const publicKeyPoint = bufferToElliptic(coreKitInstance.getPubKey());
27+
assert(pubkey.eq(publicKeyPoint));
28+
}
1729
const storageInstance = new MemoryStorage();
1830
export const ImportTest = async (testVariable: ImportKeyTestVariable) => {
1931
async function newCoreKitInstance(email: string, importTssKey?: string) {
20-
return newCoreKitLogInInstance({
21-
network: WEB3AUTH_NETWORK.DEVNET,
22-
manualSync: testVariable.manualSync,
23-
email: email,
24-
storageInstance,
25-
tssLib: testVariable.tssLib,
26-
importTssKey,
27-
});
32+
const instance = new Web3AuthMPCCoreKit({
33+
web3AuthClientId: "torus-key-test",
34+
web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET,
35+
baseUrl: "http://localhost:3000",
36+
uxMode: "nodejs",
37+
tssLib: testVariable.tssLib,
38+
storage: storageInstance,
39+
manualSync: testVariable.manualSync,
40+
disableSessionManager: true
41+
});
42+
43+
const { idToken, parsedToken } = await mockLogin(email);
44+
await instance.init({ handleRedirectResult: false, rehydrate: false });
45+
await instance.loginWithJWT({
46+
verifier: "torus-test-health",
47+
verifierId: parsedToken.email,
48+
idToken,
49+
importTssKey
50+
});
51+
return instance;
52+
2853
}
2954

3055
async function resetAccount(email: string) {
3156
const kit = await newCoreKitInstance(email);
57+
console.log('tss pub key', kit.state.tssPubKey)
3258
await criticalResetAccount(kit);
59+
if (testVariable.manualSync) {
60+
await kit.commitChanges();
61+
}
3362
await kit.logout();
34-
await new AsyncStorage(kit._storageKey, storageInstance).resetStore();
63+
// await new AsyncStorage(kit._storageKey, storageInstance).resetStore();
3564
}
3665

3766
test(`import recover tss key : ${testVariable.manualSync}`, async function (t) {
@@ -50,6 +79,9 @@ export const ImportTest = async (testVariable: ImportKeyTestVariable) => {
5079
shareType: TssShareType.DEVICE,
5180
});
5281

82+
if (testVariable.tssLib.keyType === KeyType.secp256k1) {
83+
await signSecp256k1Data({ coreKitInstance, msg: "hello world" });
84+
}
5385
const factorKeyRecovery = await coreKitInstance.createFactor({
5486
shareType: TssShareType.RECOVERY,
5587
});
@@ -62,8 +94,21 @@ export const ImportTest = async (testVariable: ImportKeyTestVariable) => {
6294
const exportedTssKey1 = await coreKitInstance._UNSAFE_exportTssKey();
6395
await coreKitInstance.logout();
6496

97+
const instance = new Web3AuthMPCCoreKit({
98+
web3AuthClientId: "torus-key-test",
99+
web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET,
100+
baseUrl: "http://localhost:3000",
101+
uxMode: "nodejs",
102+
tssLib: testVariable.tssLib,
103+
storage: storageInstance,
104+
manualSync: testVariable.manualSync,
105+
disableSessionManager: true
106+
});
107+
108+
await instance.init({rehydrate: false, handleRedirectResult: false})
109+
65110
// Recover key from any two factors.
66-
const recoveredTssKey = await coreKitInstance._UNSAFE_recoverTssKey([factorKeyDevice, factorKeyRecovery]);
111+
const recoveredTssKey = await instance._UNSAFE_recoverTssKey([factorKeyDevice, factorKeyRecovery]);
67112
assert.strictEqual(recoveredTssKey, exportedTssKey1);
68113

69114
// Initialize new instance and import existing key.
@@ -105,9 +150,9 @@ export const ImportTest = async (testVariable: ImportKeyTestVariable) => {
105150
};
106151

107152
const variable: ImportKeyTestVariable[] = [
108-
{ manualSync: false, email: "emailexport", importKeyEmail: "emailimport", tssLib: tssLibDKLS },
109-
{ manualSync: true, email: "emailexport", importKeyEmail: "emailimport", tssLib: tssLibDKLS },
110-
{ manualSync: false, email: "emailexport_ed25519", importKeyEmail: "emailimport_ed25519", tssLib: tssLibFROST },
153+
{ manualSync: false, email: "emailexport-01", importKeyEmail: "emailimport-001", tssLib: tssLibDKLS },
154+
{ manualSync: true, email: "emailexport-01", importKeyEmail: "emailimport-001", tssLib: tssLibDKLS },
155+
// { manualSync: false, email: "emailexport_ed25519", importKeyEmail: "emailimport_ed25519", tssLib: tssLibFROST },
111156
];
112157

113158
variable.forEach(async (testVariable) => {

0 commit comments

Comments
 (0)