Skip to content

Commit 217edd2

Browse files
committed
add bip340 test
1 parent b34e57b commit 217edd2

File tree

6 files changed

+222
-25
lines changed

6 files changed

+222
-25
lines changed

package-lock.json

Lines changed: 44 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@
5555
"@toruslabs/fetch-node-details": "^14.0.1",
5656
"@toruslabs/fnd-base": "^14.0.0",
5757
"@toruslabs/metadata-helpers": "^6.0.0",
58-
"@toruslabs/session-manager": "^3.1.0",
5958
"@toruslabs/openlogin-utils": "^8.2.1",
59+
"@toruslabs/session-manager": "^3.1.0",
6060
"@toruslabs/torus.js": "^15.1.0",
6161
"@toruslabs/tss-client": "^3.3.0-alpha.0",
6262
"@toruslabs/tss-frost-client": "^1.0.0-alpha.0",
@@ -68,6 +68,7 @@
6868
},
6969
"devDependencies": {
7070
"@babel/register": "^7.25.7",
71+
"@noble/curves": "^1.6.0",
7172
"@toruslabs/config": "^2.2.0",
7273
"@toruslabs/eslint-config-typescript": "^3.3.3",
7374
"@toruslabs/torus-scripts": "^6.1.2",

src/mpcCoreKit.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,13 +672,31 @@ export class Web3AuthMPCCoreKit implements ICoreKit {
672672
/**
673673
* Get public key in ed25519 format.
674674
*
675-
* Throws an error if keytype is not compatible with ed25519.
675+
* Throws an error if signature type is not ed25519.
676676
*/
677677
public getPubKeyEd25519(): Buffer {
678+
if (this._sigType !== SigType.ed25519) {
679+
throw CoreKitError.default(`getPubKeyEd25519 not supported for signature type ${this.sigType}`);
680+
}
681+
678682
const p = this.tkey.tssCurve.keyFromPublic(this.getPubKey()).getPublic();
679683
return ed25519().keyFromPublic(p).getPublic();
680684
}
681685

686+
/**
687+
* Get public key in bip340 format.
688+
*
689+
* Throws an error if signature type is not bip340.
690+
*/
691+
public getPubKeyBip340(): Buffer {
692+
if (this._sigType !== SigType.bip340) {
693+
throw CoreKitError.default(`getPubKeyBip340 not supported for signature type ${this.sigType}`);
694+
}
695+
696+
const p = this.tkey.tssCurve.keyFromPublic(this.getPubKey()).getPublic();
697+
return p.getX().toBuffer("be", 32);
698+
}
699+
682700
public async precompute_secp256k1(): Promise<{
683701
client: Client;
684702
serverCoeffs: Record<string, string>;

tests/bip340.spec.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import assert from "node:assert";
2+
import test from "node:test";
3+
4+
import { EllipticPoint } from "@tkey/common-types";
5+
import { UX_MODE_TYPE } from "@toruslabs/customauth";
6+
import { tssLib } from "@toruslabs/tss-frost-lib-bip340";
7+
import BN from "bn.js";
8+
import { schnorr as bip340 } from '@noble/curves/secp256k1';
9+
10+
import { AsyncStorage, COREKIT_STATUS, MemoryStorage, WEB3AUTH_NETWORK, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit } from "../src";
11+
import { bufferToElliptic, criticalResetAccount, mockLogin, mockLogin2 } from "./setup";
12+
13+
type TestVariable = {
14+
web3AuthNetwork: WEB3AUTH_NETWORK_TYPE;
15+
uxMode: UX_MODE_TYPE | "nodejs";
16+
manualSync?: boolean;
17+
email: string;
18+
};
19+
20+
const defaultTestEmail = "testEmailForLoginBip340";
21+
const variable: TestVariable[] = [
22+
{ web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET, uxMode: "nodejs", email: defaultTestEmail },
23+
// { web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET, uxMode: UX_MODE.REDIRECT, email: defaultTestEmail },
24+
25+
{ web3AuthNetwork: WEB3AUTH_NETWORK.DEVNET, uxMode: "nodejs", manualSync: true, email: defaultTestEmail },
26+
// { web3AuthNetwork: WEB3AUTH_NETWORK.MAINNET, uxMode: UX_MODE.REDIRECT, manualSync: true, email: defaultTestEmail },
27+
];
28+
29+
const checkLogin = async (coreKitInstance: Web3AuthMPCCoreKit, accountIndex = 0) => {
30+
const keyDetails = coreKitInstance.getKeyDetails();
31+
assert.strictEqual(coreKitInstance.status, COREKIT_STATUS.LOGGED_IN);
32+
assert.strictEqual(keyDetails.requiredFactors, 0);
33+
const factorkey = coreKitInstance.getCurrentFactorKey();
34+
await coreKitInstance.tKey.getTSSShare(new BN(factorkey.factorKey, "hex"), {
35+
accountIndex,
36+
});
37+
};
38+
39+
const storageInstance = new MemoryStorage();
40+
41+
variable.forEach((testVariable) => {
42+
const { web3AuthNetwork, uxMode, manualSync, email } = testVariable;
43+
const newCoreKitInstance = () =>
44+
new Web3AuthMPCCoreKit({
45+
web3AuthClientId: "torus-key-test",
46+
web3AuthNetwork,
47+
baseUrl: "http://localhost:3000",
48+
uxMode,
49+
tssLib,
50+
storage: storageInstance,
51+
manualSync,
52+
});
53+
54+
async function resetAccount() {
55+
const resetInstance = newCoreKitInstance();
56+
const { idToken, parsedToken } = await mockLogin(email);
57+
await resetInstance.init({ handleRedirectResult: false, rehydrate: false });
58+
await resetInstance.loginWithJWT({
59+
verifier: "torus-test-health",
60+
verifierId: parsedToken.email,
61+
idToken,
62+
});
63+
await criticalResetAccount(resetInstance);
64+
await new AsyncStorage(resetInstance._storageKey, storageInstance).resetStore();
65+
}
66+
67+
const testNameSuffix = JSON.stringify(testVariable);
68+
69+
let checkPubKey: EllipticPoint;
70+
let checkTssShare: BN;
71+
72+
test(`#Login Test with JWT + logout: ${testNameSuffix}`, async (t) => {
73+
await resetAccount();
74+
await t.test("#Login", async function () {
75+
const coreKitInstance = newCoreKitInstance();
76+
77+
// mocklogin
78+
const { idToken, parsedToken } = await mockLogin(email);
79+
await coreKitInstance.init({ handleRedirectResult: false });
80+
await coreKitInstance.loginWithJWT({
81+
verifier: "torus-test-health",
82+
verifierId: parsedToken.email,
83+
idToken,
84+
});
85+
// get key details
86+
await checkLogin(coreKitInstance);
87+
88+
checkPubKey = bufferToElliptic(coreKitInstance.getPubKey(), coreKitInstance.tKey.tssCurve);
89+
const factorkey = coreKitInstance.getCurrentFactorKey();
90+
const { tssShare } = await coreKitInstance.tKey.getTSSShare(new BN(factorkey.factorKey, "hex"), {
91+
threshold: 0,
92+
});
93+
checkTssShare = tssShare;
94+
95+
if (manualSync) {
96+
await coreKitInstance.commitChanges();
97+
}
98+
// check whether the public key and tss share is same as old sdks
99+
});
100+
101+
await t.test("#relogin ", async function () {
102+
const coreKitInstance = newCoreKitInstance();
103+
// rehydrate
104+
await coreKitInstance.init({ handleRedirectResult: false });
105+
await checkLogin(coreKitInstance);
106+
107+
// logout
108+
await coreKitInstance.logout();
109+
110+
// rehydrate should fail
111+
await coreKitInstance.init({
112+
rehydrate: false,
113+
handleRedirectResult: false,
114+
});
115+
assert.strictEqual(coreKitInstance.status, COREKIT_STATUS.INITIALIZED);
116+
assert.throws(() => coreKitInstance.getCurrentFactorKey());
117+
118+
// relogin
119+
const { idToken, parsedToken } = await mockLogin(email);
120+
await coreKitInstance.loginWithJWT({
121+
verifier: "torus-test-health",
122+
verifierId: parsedToken.email,
123+
idToken,
124+
});
125+
126+
// get key details
127+
await checkLogin(coreKitInstance);
128+
const newPubKey = bufferToElliptic(coreKitInstance.getPubKey(), coreKitInstance.tKey.tssCurve);
129+
const factorkey = coreKitInstance.getCurrentFactorKey();
130+
const { tssShare: newTssShare } = await coreKitInstance.tKey.getTSSShare(new BN(factorkey.factorKey, "hex"));
131+
assert(checkPubKey.eq(newPubKey));
132+
assert(checkTssShare.eq(newTssShare));
133+
});
134+
135+
await t.test("#able to sign", async function () {
136+
const coreKitInstance = newCoreKitInstance();
137+
await coreKitInstance.init({ handleRedirectResult: false, rehydrate: false });
138+
const localToken = await mockLogin2(email);
139+
await coreKitInstance.loginWithJWT({
140+
verifier: "torus-test-health",
141+
verifierId: email,
142+
idToken: localToken.idToken,
143+
});
144+
const msg = "hello world";
145+
const msgBuffer = Buffer.from(msg);
146+
147+
const signature = await coreKitInstance.sign(msgBuffer);
148+
const pk = coreKitInstance.getPubKeyBip340();
149+
const valid = bip340.verify(signature, msgBuffer, pk);
150+
assert(valid);
151+
});
152+
});
153+
});

tests/importRecovery.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ 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, TssLib, TssShareType, WEB3AUTH_NETWORK } from "../src";
7+
import { AsyncStorage, MemoryStorage, TssLibType, TssShareType, WEB3AUTH_NETWORK } from "../src";
88
import { bufferToElliptic, criticalResetAccount, newCoreKitLogInInstance } from "./setup";
99

1010
type ImportKeyTestVariable = {
1111
manualSync?: boolean;
1212
email: string;
1313
importKeyEmail: string;
14-
tssLib: TssLib;
14+
tssLib: TssLibType;
1515
};
1616

1717
const storageInstance = new MemoryStorage();

tests/setup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import BN from "bn.js";
44
import jwt, { Algorithm } from "jsonwebtoken";
55
import { tssLib as tssLibDKLS } from "@toruslabs/tss-dkls-lib";
66

7-
import { IAsyncStorage, IStorage, parseToken, TssLib, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit } from "../src";
7+
import { IAsyncStorage, IStorage, parseToken, TssLibType, WEB3AUTH_NETWORK_TYPE, Web3AuthMPCCoreKit } from "../src";
88

99
export const mockLogin2 = async (email: string) => {
1010
const req = new Request("https://li6lnimoyrwgn2iuqtgdwlrwvq0upwtr.lambda-url.eu-west-1.on.aws/", {
@@ -97,7 +97,7 @@ export const newCoreKitLogInInstance = async ({
9797
manualSync: boolean;
9898
email: string;
9999
storageInstance: IStorage | IAsyncStorage;
100-
tssLib?: TssLib;
100+
tssLib?: TssLibType;
101101
importTssKey?: string;
102102
login?: LoginFunc;
103103
}) => {

0 commit comments

Comments
 (0)