From 1789692943d7e00591957c800704c13ab5df8d20 Mon Sep 17 00:00:00 2001 From: weechien <83656073+huggingbot@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:46:27 +0800 Subject: [PATCH 01/56] [IRT-741] feat: Enable share import to call only to a proxy server instead of calling to all endpoints --- src/constants.ts | 1 + src/helpers/nodeUtils.ts | 119 ++++++++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index b2f47dd..5057259 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,6 +2,7 @@ export const JRPC_METHODS = { GET_OR_SET_KEY: "GetPubKeyOrKeyAssign", COMMITMENT_REQUEST: "CommitmentRequest", IMPORT_SHARE: "ImportShare", + IMPORT_SHARES: "ImportShares", GET_SHARE_OR_KEY_ASSIGN: "GetShareOrKeyAssign", }; diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 346d61d..bc71266 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -223,57 +223,71 @@ export async function retrieveOrImportShare(params: { return Promise.reject(new Error(`invalid ${JSON.stringify(resultArr)}`)); }) .then((responses) => { - const promiseArrRequest: Promise>[] = []; + const promiseArrRequest: Promise | JRPCResponse>[] = []; const nodeSigs: CommitmentRequestResult[] = []; for (let i = 0; i < responses.length; i += 1) { const x = responses[i]; - if (!x || typeof x !== "object") { - continue; - } - if (x.error) { + if (!x || typeof x !== "object" || x.error) { continue; } if (x) nodeSigs.push((x as JRPCResponse).result); } - for (let i = 0; i < endpoints.length; i += 1) { - const x = responses[i]; - if (!x || typeof x !== "object") { - continue; - } - if (x.error) { - continue; + + if (isImportShareReq) { + const importedPubKey = ecCurve.keyFromPublic({ x: importedShares[0].pub_key_x, y: importedShares[0].pub_key_x }).getPublic(); + const importedPubKeyStr = importedPubKey.encode("hex", false).slice(2); + const hashedImportedPubKey = keccak256(Buffer.from(importedPubKeyStr, "utf8")); + const proxyEndpointNum = parseInt(hashedImportedPubKey, 16) % endpoints.length; + const sortedEndpoints = [endpoints[proxyEndpointNum], ...endpoints.slice(0, proxyEndpointNum), ...endpoints.slice(proxyEndpointNum + 1)]; + const sortedImportedShares = [ + importedShares[proxyEndpointNum], + ...importedShares.slice(0, proxyEndpointNum), + ...importedShares.slice(proxyEndpointNum + 1), + ]; + + const items: Record[] = []; + for (let i = 0; i < endpoints.length; i += 1) { + const x = responses[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } + const importedShare = sortedImportedShares[i]; + items.push({ + ...verifierParams, + idtoken: idToken, + nodesignatures: nodeSigs, + verifieridentifier: verifier, + pub_key_x: importedShare.pub_key_x, + pub_key_y: importedShare.pub_key_y, + encrypted_share: importedShare.encrypted_share, + encrypted_share_metadata: importedShare.encrypted_share_metadata, + node_index: importedShare.node_index, + key_type: importedShare.key_type, + nonce_data: importedShare.nonce_data, + nonce_signature: importedShare.nonce_signature, + sss_endpoint: sortedEndpoints[i], + ...extraParams, + }); } - if (isImportShareReq) { - const importedShare = importedShares[i]; - const p = post>( - endpoints[i], - generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARE, { - encrypted: "yes", - use_temp: true, - item: [ - { - ...verifierParams, - idtoken: idToken, - nodesignatures: nodeSigs, - verifieridentifier: verifier, - pub_key_x: importedShare.pub_key_x, - pub_key_y: importedShare.pub_key_y, - encrypted_share: importedShare.encrypted_share, - encrypted_share_metadata: importedShare.encrypted_share_metadata, - node_index: importedShare.node_index, - key_type: importedShare.key_type, - nonce_data: importedShare.nonce_data, - nonce_signature: importedShare.nonce_signature, - ...extraParams, - }, - ], - one_key_flow: true, - }), - null, - { logTracingHeader: config.logRequestTracing } - ).catch((err) => log.error("share req", err)); - promiseArrRequest.push(p); - } else { + + const p = post>( + sortedEndpoints[0], + generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARES, { + encrypted: "yes", + use_temp: true, + item: items, + one_key_flow: true, + }), + null, + { logTracingHeader: config.logRequestTracing } + ).catch((err) => log.error("share req", err)); + promiseArrRequest.push(p); + } else { + for (let i = 0; i < endpoints.length; i += 1) { + const x = responses[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } const p = post>( endpoints[i], generateJsonRPCObject(JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN, { @@ -298,10 +312,25 @@ export async function retrieveOrImportShare(params: { } let thresholdNonceData: GetOrSetNonceResult; return Some< - void | JRPCResponse, + void | JRPCResponse | JRPCResponse, | { privateKey: BN; sessionTokenData: SessionToken[]; thresholdNonceData: GetOrSetNonceResult; nodeIndexes: BN[]; isNewKey: boolean } | undefined - >(promiseArrRequest, async (shareResponses, sharedState) => { + >(promiseArrRequest, async (shareResponseResult, sharedState) => { + let shareResponses: (void | JRPCResponse)[] = []; + if (shareResponseResult.length === 1 && shareResponseResult[0] && Array.isArray(shareResponseResult[0].result)) { + // this is for import shares + const importedSharesResult = shareResponseResult[0]; + shareResponseResult[0].result.forEach((res) => { + shareResponses.push({ + id: importedSharesResult.id, + jsonrpc: "2.0", + result: res, + error: importedSharesResult.error, + }); + }); + } else { + shareResponses = shareResponseResult as (void | JRPCResponse)[]; + } // check if threshold number of nodes have returned the same user public key const completedRequests = shareResponses.filter((x) => { if (!x || typeof x !== "object") { From b624844d5f182f79c778bd3396065d7dd816ff86 Mon Sep 17 00:00:00 2001 From: weechien <83656073+huggingbot@users.noreply.github.com> Date: Mon, 2 Oct 2023 15:33:03 +0800 Subject: [PATCH 02/56] [IRT-741] fix: Use hash of verifier and verifierId rather thn pub keys --- src/helpers/nodeUtils.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index bc71266..a709f7b 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -234,10 +234,9 @@ export async function retrieveOrImportShare(params: { } if (isImportShareReq) { - const importedPubKey = ecCurve.keyFromPublic({ x: importedShares[0].pub_key_x, y: importedShares[0].pub_key_x }).getPublic(); - const importedPubKeyStr = importedPubKey.encode("hex", false).slice(2); - const hashedImportedPubKey = keccak256(Buffer.from(importedPubKeyStr, "utf8")); - const proxyEndpointNum = parseInt(hashedImportedPubKey, 16) % endpoints.length; + const verifierIdStr = `${verifier}${verifierParams.verifier_id}`; + const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); + const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; const sortedEndpoints = [endpoints[proxyEndpointNum], ...endpoints.slice(0, proxyEndpointNum), ...endpoints.slice(proxyEndpointNum + 1)]; const sortedImportedShares = [ importedShares[proxyEndpointNum], From 7d2fc602fc8195f5d5ba65d9588b50008a53b9b8 Mon Sep 17 00:00:00 2001 From: weechien <83656073+huggingbot@users.noreply.github.com> Date: Tue, 3 Oct 2023 10:47:34 +0800 Subject: [PATCH 03/56] [IRT-741] fix: Remove sorting shares as we will map data on backend to corresponding nodes using node indexes --- src/helpers/nodeUtils.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index a709f7b..7b5b48c 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -237,12 +237,6 @@ export async function retrieveOrImportShare(params: { const verifierIdStr = `${verifier}${verifierParams.verifier_id}`; const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; - const sortedEndpoints = [endpoints[proxyEndpointNum], ...endpoints.slice(0, proxyEndpointNum), ...endpoints.slice(proxyEndpointNum + 1)]; - const sortedImportedShares = [ - importedShares[proxyEndpointNum], - ...importedShares.slice(0, proxyEndpointNum), - ...importedShares.slice(proxyEndpointNum + 1), - ]; const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { @@ -250,7 +244,7 @@ export async function retrieveOrImportShare(params: { if (!x || typeof x !== "object" || x.error) { continue; } - const importedShare = sortedImportedShares[i]; + const importedShare = importedShares[i]; items.push({ ...verifierParams, idtoken: idToken, @@ -264,13 +258,13 @@ export async function retrieveOrImportShare(params: { key_type: importedShare.key_type, nonce_data: importedShare.nonce_data, nonce_signature: importedShare.nonce_signature, - sss_endpoint: sortedEndpoints[i], + sss_endpoint: endpoints[i], ...extraParams, }); } const p = post>( - sortedEndpoints[0], + endpoints[proxyEndpointNum], generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARES, { encrypted: "yes", use_temp: true, From 99bc575df22fe1f54daae041b31780856987f305 Mon Sep 17 00:00:00 2001 From: weechien <83656073+huggingbot@users.noreply.github.com> Date: Tue, 3 Oct 2023 13:18:12 +0800 Subject: [PATCH 04/56] [IRT-741] fix: Remove unused constant --- src/constants.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 5057259..a23cac8 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,7 +1,6 @@ export const JRPC_METHODS = { GET_OR_SET_KEY: "GetPubKeyOrKeyAssign", COMMITMENT_REQUEST: "CommitmentRequest", - IMPORT_SHARE: "ImportShare", IMPORT_SHARES: "ImportShares", GET_SHARE_OR_KEY_ASSIGN: "GetShareOrKeyAssign", }; From a957ebf2f9c1391dedb8ff5d1dadee33942ab515 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 24 Oct 2023 23:07:54 +0800 Subject: [PATCH 05/56] import share tests fixed --- src/helpers/nodeUtils.ts | 2 +- test/sapphire_devnet.test.ts | 8 +++++--- test/sapphire_mainnet.test.ts | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 7b5b48c..fce6b6e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -237,7 +237,6 @@ export async function retrieveOrImportShare(params: { const verifierIdStr = `${verifier}${verifierParams.verifier_id}`; const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; - const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { const x = responses[i]; @@ -310,6 +309,7 @@ export async function retrieveOrImportShare(params: { | undefined >(promiseArrRequest, async (shareResponseResult, sharedState) => { let shareResponses: (void | JRPCResponse)[] = []; + // for import shares case, where result is an array if (shareResponseResult.length === 1 && shareResponseResult[0] && Array.isArray(shareResponseResult[0].result)) { // this is for import shares const importedSharesResult = shareResponseResult[0]; diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index e9bddc1..572b039 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -10,7 +10,7 @@ import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "saasas@tr.us"; -const TORUS_IMPORT_EMAIL = "importeduser5@tor.us"; +const TORUS_IMPORT_EMAIL = "Elena_Hermann@yahoo.com"; const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"; @@ -286,7 +286,7 @@ describe("torus utils sapphire", function () { }); it("should be able to key assign", async function () { - const email = faker.internet.email(); + const email = `${faker.internet.email()}`; const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; @@ -396,8 +396,10 @@ describe("torus utils sapphire", function () { privHex ); expect(result.finalKeyData.privKey).to.be.equal(privHex); + const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, verifierId: email }); + expect(result1.finalKeyData.evmAddress).to.be.equal(result.finalKeyData.evmAddress); }); - it.skip("should be able to import a key for a existing user", async function () { + it("should be able to import a key for a existing user", async function () { let verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index ec52821..13997d8 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -58,7 +58,7 @@ describe("torus utils sapphire mainnet", function () { }); }); - it("should be able to import a key for a new user", async function () { + it.skip("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); const privKeyBuffer = generatePrivate(); From 8586ecc22098e35bce0df0136ea3c05483ea8b08 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 30 Nov 2023 04:17:29 +0800 Subject: [PATCH 06/56] add ed25519 key support --- src/helpers/keyUtils.ts | 7 ++++- src/helpers/metadataUtils.ts | 11 +++++--- src/helpers/nodeUtils.ts | 25 +++++++++--------- src/interfaces.ts | 4 +++ src/torus.ts | 50 ++++++++++++++++++++++++------------ test/sapphire_devnet.test.ts | 2 +- 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 6807359..1e21adf 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,5 +1,5 @@ import BN from "bn.js"; -import { ec } from "elliptic"; +import { curve, ec } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import log from "../loglevel"; @@ -52,3 +52,8 @@ export function getPostboxKeyFrom1OutOf1(ecCurve: ec, privKey: string, nonce: st const nonceBN = new BN(nonce, 16); return privKeyBN.sub(nonceBN).umod(ecCurve.curve.n).toString("hex"); } + +export function derivePubKey(ecCurve: ec, sk: BN): curve.base.BasePoint { + const skHex = sk.toString(16, 64); + return ecCurve.keyFromPrivate(skHex).getPublic(); +} diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 9a9db05..99dafd2 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -5,7 +5,7 @@ import { ec } from "elliptic"; import stringify from "json-stable-stringify"; import log from "loglevel"; -import { EciesHex, GetOrSetNonceResult, MetadataParams } from "../interfaces"; +import { EciesHex, GetOrSetNonceResult, KeyType, MetadataParams } from "../interfaces"; import { encParamsHexToBuf } from "./common"; import { keccak256 } from "./keyUtils"; @@ -25,7 +25,7 @@ export async function decryptNodeData(eciesData: EciesHex, ciphertextHex: string return decryptedSigBuffer; } -export function generateMetadataParams(ecCurve: ec, serverTimeOffset: number, message: string, privateKey: BN): MetadataParams { +export function generateMetadataParams(ecCurve: ec, serverTimeOffset: number, message: string, privateKey: BN, keyType: KeyType): MetadataParams { const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); const setData = { data: message, @@ -36,6 +36,7 @@ export function generateMetadataParams(ecCurve: ec, serverTimeOffset: number, me pub_key_X: key.getPublic().getX().toString("hex"), // DO NOT PAD THIS. BACKEND DOESN'T pub_key_Y: key.getPublic().getY().toString("hex"), // DO NOT PAD THIS. BACKEND DOESN'T set_data: setData, + key_type: keyType, signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), }; } @@ -60,6 +61,7 @@ export async function getMetadata( export async function getOrSetNonce( legacyMetadataHost: string, ecCurve: ec, + keyType: KeyType, serverTimeOffset: number, X: string, Y: string, @@ -69,7 +71,7 @@ export async function getOrSetNonce( let data: Data; const msg = getOnly ? "getNonce" : "getOrSetNonce"; if (privKey) { - data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey); + data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey, keyType); } else { data = { pub_key_X: X, @@ -83,10 +85,11 @@ export async function getOrSetNonce( export async function getNonce( legacyMetadataHost: string, ecCurve: ec, + keyType: KeyType, serverTimeOffset: number, X: string, Y: string, privKey?: BN ): Promise { - return getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, X, Y, privKey, true); + return getOrSetNonce(legacyMetadataHost, ecCurve, keyType, serverTimeOffset, X, Y, privKey, true); } diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index a0fbaaa..4945843 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -14,6 +14,7 @@ import { JRPCResponse, KeyAssignInput, KeyLookupResult, + KeyType, LegacyKeyLookupResult, LegacyVerifierLookupResponse, SessionToken, @@ -28,7 +29,7 @@ import { import log from "../loglevel"; import { Some } from "../some"; import { kCombinations, normalizeKeysResult, thresholdSame } from "./common"; -import { generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -118,6 +119,7 @@ export async function retrieveOrImportShare(params: { serverTimeOffset: number; enableOneKey: boolean; ecCurve: ec; + keyType: KeyType; allowHost: string; network: string; clientId: string; @@ -133,6 +135,7 @@ export async function retrieveOrImportShare(params: { serverTimeOffset, enableOneKey, ecCurve, + keyType, allowHost, network, clientId, @@ -480,13 +483,10 @@ export async function retrieveOrImportShare(params: { const indices = currentCombiShares.map((x) => x.index); const derivedPrivateKey = lagrangeInterpolation(ecCurve, shares, indices); if (!derivedPrivateKey) continue; - const decryptedPubKey = getPublic(Buffer.from(derivedPrivateKey.toString(16, 64), "hex")).toString("hex"); - const decryptedPubKeyX = decryptedPubKey.slice(2, 66); - const decryptedPubKeyY = decryptedPubKey.slice(66); - if ( - new BN(decryptedPubKeyX, 16).cmp(new BN(thresholdPublicKey.X, 16)) === 0 && - new BN(decryptedPubKeyY, 16).cmp(new BN(thresholdPublicKey.Y, 16)) === 0 - ) { + const decryptedPubKey = derivePubKey(ecCurve, derivedPrivateKey); + const decryptedPubKeyX = decryptedPubKey.getX(); + const decryptedPubKeyY = decryptedPubKey.getY(); + if (decryptedPubKeyX.cmp(new BN(thresholdPublicKey.X, 16)) === 0 && decryptedPubKeyY.cmp(new BN(thresholdPublicKey.Y, 16)) === 0) { privateKey = derivedPrivateKey; break; } @@ -507,9 +507,10 @@ export async function retrieveOrImportShare(params: { let nonceResult = thresholdNonceData; if (!privateKey) throw new Error("Invalid private key returned"); const oAuthKey = privateKey; - const oAuthPubKey = getPublic(Buffer.from(oAuthKey.toString(16, 64), "hex")).toString("hex"); - const oAuthPubkeyX = oAuthPubKey.slice(2, 66); - const oAuthPubkeyY = oAuthPubKey.slice(66); + const oAuthPubKey = derivePubKey(ecCurve, oAuthKey); + const oAuthPubkeyX = oAuthPubKey.getX().toString("hex"); + const oAuthPubkeyY = oAuthPubKey.getY().toString("hex"); + let metadataNonce = new BN(nonceResult?.nonce ? nonceResult.nonce.padStart(64, "0") : "0", "hex"); let finalPubKey: curve.base.BasePoint; let pubNonce: { X: string; Y: string } | undefined; @@ -522,7 +523,7 @@ export async function retrieveOrImportShare(params: { finalPubKey = ecCurve.keyFromPublic({ x: oAuthPubkeyX, y: oAuthPubkeyY }).getPublic(); } else if (LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { if (enableOneKey) { - nonceResult = await getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, oAuthPubkeyX, oAuthPubkeyY, oAuthKey, !isNewKey); + nonceResult = await getOrSetNonce(legacyMetadataHost, ecCurve, keyType, serverTimeOffset, oAuthPubkeyX, oAuthPubkeyY, oAuthKey, !isNewKey); metadataNonce = new BN(nonceResult.nonce || "0", 16); typeOfUser = nonceResult.typeOfUser; if (typeOfUser === "v2") { diff --git a/src/interfaces.ts b/src/interfaces.ts index f33f005..b5bb583 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -13,11 +13,13 @@ export type v2NonceResultType = { typeOfUser: "v2"; nonce?: string; pubNonce: { export type v1NonceResultType = { typeOfUser: "v1"; nonce?: string }; export type GetOrSetNonceResult = v2NonceResultType | v1NonceResultType; +export type KeyType = "secp256k1" | "ed25519"; export interface SetNonceData { operation: string; data: string; timestamp: string; + key_type?: KeyType; } export interface NonceMetadataParams { @@ -31,6 +33,7 @@ export interface NonceMetadataParams { export interface TorusCtorOptions { clientId: string; network: TORUS_NETWORK_TYPE; + keyType?: KeyType; enableOneKey?: boolean; serverTimeOffset?: number; allowHost?: string; @@ -222,6 +225,7 @@ export interface MetadataParams { namespace?: string; pub_key_X: string; pub_key_Y: string; + key_type?: KeyType; set_data: { data: "getNonce" | "getOrSetNonce" | string; timestamp: string; diff --git a/src/torus.ts b/src/torus.ts index 44a9156..657c2d7 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -15,6 +15,7 @@ import stringify from "json-stable-stringify"; import { config } from "./config"; import { + derivePubKey, encParamsBufToHex, generateAddressFromPrivKey, generateAddressFromPubKey, @@ -37,6 +38,7 @@ import { CommitmentRequestResult, GetOrSetNonceResult, ImportedShare, + KeyType, LegacyShareRequestResult, LegacyVerifierLookupResponse, NonceMetadataParams, @@ -70,10 +72,22 @@ class Torus { private legacyMetadataHost: string; - constructor({ enableOneKey = false, clientId, network, serverTimeOffset = 0, allowHost, legacyMetadataHost }: TorusCtorOptions) { + private _keyType: KeyType = "secp256k1"; + + constructor({ + enableOneKey = false, + clientId, + network, + serverTimeOffset = 0, + allowHost, + legacyMetadataHost, + keyType = "secp256k1", + }: TorusCtorOptions) { if (!clientId) throw Error("Please provide a valid clientId in constructor"); if (!network) throw Error("Please provide a valid network in constructor"); - this.ec = new EC("secp256k1"); + + this._keyType = keyType; + this.ec = new EC(this._keyType); this.serverTimeOffset = serverTimeOffset || 0; // ms this.network = network; this.clientId = clientId; @@ -129,6 +143,7 @@ class Torus { serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, + keyType: this._keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, @@ -179,7 +194,7 @@ class Torus { const oAuthPubKey = this.ec.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); const poly = generateRandomPolynomial(this.ec, degree, oAuthKey); const shares = poly.generateShares(nodeIndexesBn); - const nonceParams = this.generateNonceMetadataParams("getOrSetNonce", oAuthKey, randomNonce); + const nonceParams = this.generateNonceMetadataParams("getOrSetNonce", oAuthKey, this._keyType, randomNonce); const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); const sharesData: ImportedShare[] = []; const encPromises: Promise[] = []; @@ -202,7 +217,7 @@ class Torus { encrypted_share: encParamsMetadata.ciphertext, encrypted_share_metadata: encParamsMetadata, node_index: Number.parseInt(shareJson.shareIndex, 16), - key_type: "secp256k1", + key_type: this._keyType, nonce_data: nonceData, nonce_signature: nonceParams.signature, }; @@ -214,6 +229,7 @@ class Torus { serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, + keyType: "secp256k1", allowHost: this.allowHost, network: this.network, clientId: this.clientId, @@ -425,13 +441,10 @@ class Torus { const indices = currentCombiShares.map((x) => x.index); const derivedPrivateKey = lagrangeInterpolation(this.ec, shares, indices); if (!derivedPrivateKey) continue; - const decryptedPubKey = getPublic(Buffer.from(derivedPrivateKey.toString(16, 64), "hex")).toString("hex"); - const decryptedPubKeyX = decryptedPubKey.slice(2, 66); - const decryptedPubKeyY = decryptedPubKey.slice(66); - if ( - new BN(decryptedPubKeyX, 16).cmp(new BN(thresholdPublicKey.X, 16)) === 0 && - new BN(decryptedPubKeyY, 16).cmp(new BN(thresholdPublicKey.Y, 16)) === 0 - ) { + const decryptedPubKey = derivePubKey(this.ec, derivedPrivateKey); + const decryptedPubKeyX = decryptedPubKey.getX(); + const decryptedPubKeyY = decryptedPubKey.getY(); + if (decryptedPubKeyX.cmp(new BN(thresholdPublicKey.X, 16)) === 0 && decryptedPubKeyY.cmp(new BN(thresholdPublicKey.Y, 16)) === 0) { privateKey = derivedPrivateKey; break; } @@ -447,15 +460,17 @@ class Torus { .then(async (returnedKey) => { const oAuthKey = returnedKey; if (!oAuthKey) throw new Error("Invalid private key returned"); - const oAuthPubKey = getPublic(Buffer.from(oAuthKey.toString(16, 64), "hex")).toString("hex"); - const oAuthKeyX = oAuthPubKey.slice(2, 66); - const oAuthKeyY = oAuthPubKey.slice(66); + + const oAuthPubKey = derivePubKey(this.ec, oAuthKey); + const oAuthKeyX = oAuthPubKey.getX().toString("hex"); + const oAuthKeyY = oAuthPubKey.getY().toString("hex"); + let metadataNonce: BN; let finalPubKey: curve.base.BasePoint; let typeOfUser: UserType = "v1"; let pubKeyNonceResult: { X: string; Y: string } | undefined; if (this.enableOneKey) { - const nonceResult = await getNonce(this.legacyMetadataHost, this.ec, this.serverTimeOffset, oAuthKeyX, oAuthKeyY, oAuthKey); + const nonceResult = await getNonce(this.legacyMetadataHost, this.ec, this._keyType, this.serverTimeOffset, oAuthKeyX, oAuthKeyY, oAuthKey); metadataNonce = new BN(nonceResult.nonce || "0", 16); typeOfUser = nonceResult.typeOfUser; if (typeOfUser === "v2") { @@ -585,10 +600,11 @@ class Torus { throw new Error(`node results do not match at final lookup ${JSON.stringify(keyResult || {})}, ${JSON.stringify(errorResult || {})}`); } - private generateNonceMetadataParams(operation: string, privateKey: BN, nonce?: BN): NonceMetadataParams { + private generateNonceMetadataParams(operation: string, privateKey: BN, keyType: KeyType, nonce?: BN): NonceMetadataParams { const key = this.ec.keyFromPrivate(privateKey.toString("hex", 64)); const setData: Partial = { operation, + key_type: keyType, timestamp: new BN(~~(this.serverTimeOffset + Date.now() / 1000)).toString(16), }; @@ -719,7 +735,7 @@ class Torus { if (enableOneKey) { try { - nonceResult = await getOrSetNonce(this.legacyMetadataHost, this.ec, this.serverTimeOffset, X, Y, undefined, !isNewKey); + nonceResult = await getOrSetNonce(this.legacyMetadataHost, this.ec, this._keyType, this.serverTimeOffset, X, Y, undefined, !isNewKey); nonce = new BN(nonceResult.nonce || "0", 16); typeOfUser = nonceResult.typeOfUser; } catch { diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index bd05d64..7a76362 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -19,7 +19,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe("torus utils sapphire devnet", function () { +describe.only("torus utils sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; From 3066336b1322b2d6a335f057055aaa4eb153fd46 Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 11 Dec 2023 15:22:50 +0800 Subject: [PATCH 07/56] add key type support for ed25519 --- .vscode/settings.json | 2 +- src/helpers/nodeUtils.ts | 37 +- src/interfaces.ts | 3 +- src/loglevel.ts | 2 +- src/torus.ts | 18 +- test/helpers.ts | 2 +- test/sapphire_devnet.test.ts | 2 +- test/sapphire_devnet_ed25519.test.ts | 548 +++++++++++++++++++++++++++ 8 files changed, 597 insertions(+), 17 deletions(-) create mode 100644 test/sapphire_devnet_ed25519.test.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 5b39903..81647c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" }, "cSpell.words": ["Mutex", "Mutexes", "toruslabs"] } diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 4945843..3349e93 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -38,9 +38,10 @@ export const GetPubKeyOrKeyAssign = async (params: { network: TORUS_NETWORK_TYPE; verifier: string; verifierId: string; + keyType: KeyType; extendedVerifierId?: string; }): Promise => { - const { endpoints, network, verifier, verifierId, extendedVerifierId } = params; + const { endpoints, network, verifier, verifierId, extendedVerifierId, keyType } = params; const lookupPromises = endpoints.map((x) => post>( x, @@ -49,6 +50,7 @@ export const GetPubKeyOrKeyAssign = async (params: { verifier_id: verifierId.toString(), extended_verifier_id: extendedVerifierId, one_key_flow: true, + key_type: keyType, fetch_node_index: true, }), null, @@ -190,6 +192,7 @@ export async function retrieveOrImportShare(params: { endpoints[i], generateJsonRPCObject(JRPC_METHODS.COMMITMENT_REQUEST, { messageprefix: "mug00", + keytype: keyType, tokencommitment: tokenCommitment.slice(2), temppubx: pubKeyX, temppuby: pubKeyY, @@ -260,9 +263,11 @@ export async function retrieveOrImportShare(params: { generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARE, { encrypted: "yes", use_temp: true, + key_type: importedShare.key_type, item: [ { ...verifierParams, + key_type: importedShare.key_type, idtoken: idToken, nodesignatures: nodeSigs, verifieridentifier: verifier, @@ -271,7 +276,6 @@ export async function retrieveOrImportShare(params: { encrypted_share: importedShare.encrypted_share, encrypted_share_metadata: importedShare.encrypted_share_metadata, node_index: importedShare.node_index, - key_type: importedShare.key_type, nonce_data: importedShare.nonce_data, nonce_signature: importedShare.nonce_signature, ...extraParams, @@ -289,10 +293,12 @@ export async function retrieveOrImportShare(params: { generateJsonRPCObject(JRPC_METHODS.GET_SHARE_OR_KEY_ASSIGN, { encrypted: "yes", use_temp: true, + key_type: keyType, item: [ { ...verifierParams, idtoken: idToken, + key_type: keyType, nodesignatures: nodeSigs, verifieridentifier: verifier, ...extraParams, @@ -353,6 +359,7 @@ export async function retrieveOrImportShare(params: { // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key + if ( completedRequests.length >= thresholdReqCount && thresholdPublicKey && @@ -418,7 +425,9 @@ export async function retrieveOrImportShare(params: { latestKey.share_metadata, Buffer.from(latestKey.share, "base64").toString("binary").padStart(64, "0"), sessionAuthKey - ).catch((err) => log.debug("share decryption", err)) + ).catch((err) => { + log.debug("share decryption", err); + }) ); } } else { @@ -495,6 +504,7 @@ export async function retrieveOrImportShare(params: { if (privateKey === undefined || privateKey === null) { throw new Error("could not derive private key"); } + const thresholdIsNewKey = thresholdSame(isNewKeyResponses, ~~(endpoints.length / 2) + 1); return { privateKey, sessionTokenData, thresholdNonceData, nodeIndexes, isNewKey: thresholdIsNewKey === "true" }; @@ -614,13 +624,19 @@ export async function retrieveOrImportShare(params: { }); } -export const legacyKeyLookup = async (endpoints: string[], verifier: string, verifierId: string): Promise => { +export const legacyKeyLookup = async ( + endpoints: string[], + verifier: string, + verifierId: string, + keyType: KeyType +): Promise => { const lookupPromises = endpoints.map((x) => post>( x, generateJsonRPCObject("VerifierLookupRequest", { verifier, verifier_id: verifierId.toString(), + key_type: keyType, }) ).catch((err) => log.error("lookup request failed", err)) ); @@ -651,6 +667,7 @@ export const legacyKeyAssign = async ({ signerHost, network, clientId, + keyType, }: KeyAssignInput): Promise => { let nodeNum: number; let initialPoint: number | undefined; @@ -668,6 +685,7 @@ export const legacyKeyAssign = async ({ const data = generateJsonRPCObject("KeyAssign", { verifier, verifier_id: verifierId.toString(), + key_type: keyType, }); try { const signedData = await post( @@ -724,6 +742,7 @@ export const legacyKeyAssign = async ({ signerHost, network, clientId, + keyType, }); throw new Error( `Sorry, the Torus Network that powers Web3Auth is currently very busy. @@ -733,9 +752,15 @@ export const legacyKeyAssign = async ({ } }; -export const legacyWaitKeyLookup = (endpoints: string[], verifier: string, verifierId: string, timeout: number): Promise => +export const legacyWaitKeyLookup = ( + endpoints: string[], + verifier: string, + verifierId: string, + keyType: KeyType, + timeout: number +): Promise => new Promise((resolve, reject) => { setTimeout(() => { - legacyKeyLookup(endpoints, verifier, verifierId).then(resolve).catch(reject); + legacyKeyLookup(endpoints, verifier, verifierId, keyType).then(resolve).catch(reject); }, timeout); }); diff --git a/src/interfaces.ts b/src/interfaces.ts index b5bb583..dfea815 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -19,7 +19,6 @@ export interface SetNonceData { operation: string; data: string; timestamp: string; - key_type?: KeyType; } export interface NonceMetadataParams { @@ -28,6 +27,7 @@ export interface NonceMetadataParams { pub_key_Y: string; set_data: Partial; signature: string; + key_type?: KeyType; } export interface TorusCtorOptions { @@ -102,6 +102,7 @@ export interface KeyAssignInput { signerHost: string; network: string; clientId: string; + keyType: KeyType; } export type EciesHex = { diff --git a/src/loglevel.ts b/src/loglevel.ts index 1d33267..d8d3e53 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.disableAll(); +log.enableAll(); export default log; diff --git a/src/torus.ts b/src/torus.ts index 657c2d7..8273d63 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -137,7 +137,7 @@ class Torus { idToken: string, extraParams: Record = {} ): Promise { - if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, extraParams); + if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this._keyType, extraParams); return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -229,7 +229,7 @@ class Torus { serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, - keyType: "secp256k1", + keyType: this._keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, @@ -262,6 +262,7 @@ class Torus { verifier: string, verifierParams: VerifierParams, idToken: string, + keyType: KeyType, extraParams: Record = {} ): Promise { const promiseArr = []; @@ -301,6 +302,7 @@ class Torus { endpoints[i], generateJsonRPCObject("CommitmentRequest", { messageprefix: "mug00", + keytype: keyType, tokencommitment: tokenCommitment.slice(2), temppubx: pubKeyX, temppuby: pubKeyY, @@ -360,7 +362,9 @@ class Torus { endpoints[i], generateJsonRPCObject("ShareRequest", { encrypted: "yes", - item: [{ ...verifierParams, idtoken: idToken, nodesignatures: nodeSigs, verifieridentifier: verifier, ...extraParams }], + item: [ + { ...verifierParams, idtoken: idToken, nodesignatures: nodeSigs, verifieridentifier: verifier, key_type: keyType, ...extraParams }, + ], }) ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); @@ -562,7 +566,7 @@ class Torus { let finalKeyResult: LegacyVerifierLookupResponse | undefined; let isNewKey = false; - const { keyResult, errorResult } = (await legacyKeyLookup(endpoints, verifier, verifierId)) || {}; + const { keyResult, errorResult } = (await legacyKeyLookup(endpoints, verifier, verifierId, this._keyType)) || {}; if (errorResult && JSON.stringify(errorResult).includes("Verifier not supported")) { // change error msg throw new Error(`Verifier not supported. Check if you: \n @@ -579,8 +583,9 @@ class Torus { signerHost: this.signerHost, network: this.network, clientId: this.clientId, + keyType: this._keyType, }); - const assignResult = await legacyWaitKeyLookup(endpoints, verifier, verifierId, 1000); + const assignResult = await legacyWaitKeyLookup(endpoints, verifier, verifierId, this._keyType, 1000); finalKeyResult = assignResult?.keyResult; isNewKey = true; } else if (keyResult) { @@ -604,7 +609,6 @@ class Torus { const key = this.ec.keyFromPrivate(privateKey.toString("hex", 64)); const setData: Partial = { operation, - key_type: keyType, timestamp: new BN(~~(this.serverTimeOffset + Date.now() / 1000)).toString(16), }; @@ -616,6 +620,7 @@ class Torus { pub_key_X: key.getPublic().getX().toString("hex", 64), pub_key_Y: key.getPublic().getY().toString("hex", 64), set_data: setData, + key_type: keyType, signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), }; } @@ -631,6 +636,7 @@ class Torus { network: this.network, verifier, verifierId, + keyType: this._keyType, extendedVerifierId, }); const { errorResult, keyResult, nodeIndexes = [] } = keyAssignResult; diff --git a/test/helpers.ts b/test/helpers.ts index 73727b5..294501d 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -6,7 +6,7 @@ import { JRPCResponse } from "../src"; import { config } from "../src/config"; dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); -const jwtPrivateKey = `-----BEGIN PRIVATE KEY-----\n${process.env.JWT_PRIVATE_KEY}\n-----END PRIVATE KEY-----`; +const jwtPrivateKey = `-----BEGIN PRIVATE KEY-----\nMEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCD7oLrcKae+jVZPGx52Cb/lKhdKxpXjl9eGNa1MlY57A==\n-----END PRIVATE KEY-----`; export const generateIdToken = (email: string, alg: Algorithm) => { const iat = Math.floor(Date.now() / 1000); const payload = { diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 7a76362..bd05d64 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -19,7 +19,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe.only("torus utils sapphire devnet", function () { +describe("torus utils sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts new file mode 100644 index 0000000..5939cb1 --- /dev/null +++ b/test/sapphire_devnet_ed25519.test.ts @@ -0,0 +1,548 @@ +/* eslint-disable no-console */ +import { TORUS_LEGACY_NETWORK, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; +import { generatePrivate } from "@toruslabs/eccrypto"; +import NodeManager from "@toruslabs/fetch-node-details"; +import BN from "bn.js"; +import { expect } from "chai"; +import faker from "faker"; + +import { keccak256 } from "../src"; +import TorusUtils from "../src/torus"; +import { generateIdToken, lookupVerifier } from "./helpers"; + +const TORUS_TEST_EMAIL = "ed255192@tor.us"; +const TORUS_IMPORT_EMAIL = "importeduser5@tor.us"; + +const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"; + +const TORUS_TEST_VERIFIER = "torus-test-health"; + +const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; +const HashEnabledVerifier = "torus-test-verifierid-hash"; + +describe("torus utils sapphire devnet", function () { + let torus: TorusUtils; + let TORUS_NODE_MANAGER: NodeManager; + + beforeEach("one time execution before all tests", async function () { + TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET }); + torus = new TorusUtils({ + network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET, + clientId: "YOUR_CLIENT_ID", + enableOneKey: true, + keyType: "ed25519", + }); + TorusUtils.enableLogging(false); + }); + + it("should fetch user type and public address of legacy v2 user", async function () { + const LEGACY_TORUS_NODE_MANAGER = new NodeManager({ + network: TORUS_LEGACY_NETWORK.TESTNET, + // fndServerEndpoint: "http://localhost:8060/node-details", + }); + const v2Verifier = "tkey-google-lrc"; + // 1/1 user + const v2TestEmail = "somev2user@gmail.com"; + const verifierDetails = { verifier: v2Verifier, verifierId: v2TestEmail }; + + const legacyTorus = new TorusUtils({ + network: TORUS_LEGACY_NETWORK.TESTNET, + clientId: "YOUR_CLIENT_ID", + enableOneKey: true, + }); + const { torusNodeSSSEndpoints: torusNodeEndpoints, torusNodePub } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + + const result = await legacyTorus.getPublicAddress(torusNodeEndpoints, torusNodePub, { + verifier: v2Verifier, + verifierId: v2TestEmail, + }); + expect(result.finalKeyData.evmAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result).eql({ + oAuthKeyData: { + evmAddress: "0x376597141d8d219553378313d18590F373B09795", + X: "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c", + Y: "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2", + }, + finalKeyData: { + evmAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", + X: "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e", + Y: "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f", + }, + metadata: { + pubNonce: { + X: "ad121b67fa550da814bbbd54ec7070705d058c941e04c03e07967b07b2f90345", + Y: "bfe2395b177a72ebb836aaf24cedff2f14cd9ed49047990f5cdb99e4981b5753", + }, + nonce: new BN(0), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + + // 2/n user + const v2nTestEmail = "caspertorus@gmail.com"; + const data = await legacyTorus.getPublicAddress(torusNodeEndpoints, torusNodePub, { + verifier: v2Verifier, + verifierId: v2nTestEmail, + }); + expect(data.metadata.typeOfUser).to.equal("v2"); + expect(data.finalKeyData.evmAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); + expect(data).eql({ + oAuthKeyData: { + evmAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", + X: "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8", + Y: "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5", + }, + finalKeyData: { + evmAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", + X: "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7", + Y: "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222", + }, + metadata: { + pubNonce: { + X: "4f86b0e69992d1551f1b16ceb0909453dbe17b9422b030ee6c5471c2e16b65d0", + Y: "640384f3d39debb04c4e9fe5a5ec6a1b494b0ad66d00ac9be6f166f21d116ca4", + }, + nonce: new BN(0), + upgraded: true, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + + it("should fetch public address", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + console.log("result", result); + // expect(result.finalKeyData.evmAddress).to.equal("0x4924F91F5d6701dDd41042D94832bB17B76F316F"); + // expect(result).eql({ + // oAuthKeyData: { + // evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", + // X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", + // Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", + // }, + // finalKeyData: { + // evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", + // X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", + // Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", + // }, + // metadata: { + // pubNonce: { + // X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", + // Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + // }, + // nonce: new BN("0"), + // upgraded: false, + // typeOfUser: "v2", + // }, + // nodesData: result.nodesData, + // }); + }); + // we are working on a new implementation for import sss keys, so skipping it for now. + it.skip("should fetch public address of imported user", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.evmAddress).to.not.equal(""); + expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.evmAddress).to.not.equal(""); + expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.upgraded).to.equal(false); + }); + + it("should keep public address same", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: faker.internet.email() }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + + const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result1.finalKeyData).eql(result2.finalKeyData); + expect(result1.oAuthKeyData).eql(result2.oAuthKeyData); + expect(result1.metadata).eql(result2.metadata); + }); + + it("should fetch user type and public address", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.equal("0xBeB7D41966C2292eB94dfd6221834eAac496De9B"); + expect(result).eql({ + oAuthKeyData: { + evmAddress: "0x56670dF772E7e1EDe43AD174F977648b3fD96a41", + X: "7ca28464ed175b1f9596d64f068d680dd1680bce90e19360671ee7b3c284eddb", + Y: "48d5adb60735b823de4661af8d6448891bfae2373c025228ceaa0f8dce5890e9", + }, + finalKeyData: { + evmAddress: "0xBeB7D41966C2292eB94dfd6221834eAac496De9B", + X: "4e49816115c0b0e4881da707fbed70e7eb735b5e02dcce2e8c6dc009f4aedbf0", + Y: "171b2cd24deb65d145ab540b8e2cfce7d228eafd83f5ecf47417fab6f26c1aa6", + }, + metadata: { + pubNonce: { + X: "252743d769558af6441e7e1c3cbdb10dc81c0e540dcc6cfcaa64958b12ae4614", + Y: "105140f632f737b085bffc39db90fe13bf370d366502b6e58af8a323f71b76ec", + }, + nonce: new BN("0", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + + it("should be able to key assign", async function () { + const email = faker.internet.email(); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.not.equal(""); + expect(result.finalKeyData.evmAddress).to.not.equal(null); + }); + + it("should be able to login", async function () { + const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token + ); + expect(result.finalKeyData.privKey).to.be.equal("00055f150cbf9db3bf22aba13c13c87cb580b575b23e76fb97861a8a4a5f288e"); + expect(result).eql({ + finalKeyData: { + evmAddress: "0xBeB7D41966C2292eB94dfd6221834eAac496De9B", + X: "4e49816115c0b0e4881da707fbed70e7eb735b5e02dcce2e8c6dc009f4aedbf0", + Y: "171b2cd24deb65d145ab540b8e2cfce7d228eafd83f5ecf47417fab6f26c1aa6", + privKey: "00055f150cbf9db3bf22aba13c13c87cb580b575b23e76fb97861a8a4a5f288e", + }, + oAuthKeyData: { + evmAddress: "0x56670dF772E7e1EDe43AD174F977648b3fD96a41", + X: "7ca28464ed175b1f9596d64f068d680dd1680bce90e19360671ee7b3c284eddb", + Y: "48d5adb60735b823de4661af8d6448891bfae2373c025228ceaa0f8dce5890e9", + privKey: "0ec4859d312dc455c80a50bf8f1be37f81a6999b2450e8a59044c8e119f2f847", + }, + sessionData: { + sessionTokenData: result.sessionData.sessionTokenData, + sessionAuthKey: result.sessionData.sessionAuthKey, + }, + metadata: { + pubNonce: { + X: "252743d769558af6441e7e1c3cbdb10dc81c0e540dcc6cfcaa64958b12ae4614", + Y: "105140f632f737b085bffc39db90fe13bf370d366502b6e58af8a323f71b76ec", + }, + nonce: new BN("7140d977db91d95df7185ae1acf7e4fddad1eacfa5aa7508c7d46a7c181acfaf", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + + it("should be able to login even when node is down", async function () { + const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + torusNodeEndpoints[1] = "https://example.com"; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token + ); + expect(result.finalKeyData.privKey).to.be.equal("04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c"); + expect(result).eql({ + finalKeyData: { + evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", + X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", + Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", + privKey: "04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c", + }, + oAuthKeyData: { + evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", + X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", + Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", + privKey: "cd7d1dc7aec71fd2ee284890d56ac34d375bbc15ff41a1d87d088170580b9b0f", + }, + sessionData: { + sessionTokenData: result.sessionData.sessionTokenData, + sessionAuthKey: result.sessionData.sessionAuthKey, + }, + metadata: { + pubNonce: { + X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", + Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + }, + nonce: new BN("376df8a62e2e72a2b3e87e97c85f86b3f2dac41082ddeb863838d80462deab5e", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + it.only("should be able to import a key for a new user", async function () { + const email = faker.internet.email(); + const token = generateIdToken(email, "ES256"); + const privKeyBuffer = generatePrivate(); + const privHex = privKeyBuffer.toString("hex"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.importPrivateKey( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + privHex + ); + console.log("result", result); + // expect(result.finalKeyData.privKey).to.be.equal(privHex); + }); + it.skip("should be able to import a key for a existing user", async function () { + let verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const token = generateIdToken(TORUS_IMPORT_EMAIL, "ES256"); + const privKeyBuffer = generatePrivate(); + const privHex = privKeyBuffer.toString("hex"); + const result1 = await torus.importPrivateKey( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_IMPORT_EMAIL }, + token, + privHex + ); + expect(result1.finalKeyData.privKey).to.be.equal(privHex); + verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result1.finalKeyData.evmAddress).to.be.equal(result2.finalKeyData.evmAddress); + }); + + it("should fetch pub address of tss verifier id", async function () { + const email = TORUS_EXTENDED_VERIFIER_EMAIL; + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email, extendedVerifierId: tssVerifierId }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.be.equal("0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30"); + expect(result).eql({ + oAuthKeyData: { + evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", + Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", + }, + finalKeyData: { + evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", + Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", + }, + metadata: { + pubNonce: undefined, + nonce: new BN("0"), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + it("should assign key to tss verifier id", async function () { + const email = faker.internet.email(); + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email, extendedVerifierId: tssVerifierId }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.eql(new BN("0")); + expect(result.metadata.upgraded).to.equal(false); + }); + + it("should allow test tss verifier id to fetch shares", async function () { + const email = faker.internet.email(); + const nonce = 0; + const tssTag = "default"; + const tssVerifierId = `${email}\u0015${tssTag}\u0016${nonce}`; + const token = generateIdToken(email, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token + ); + expect(result.finalKeyData.privKey).to.not.equal(null); + expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.eql(new BN("0")); + expect(result.metadata.upgraded).to.equal(true); + }); + + it("should fetch public address when verifierID hash enabled", async function () { + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result).eql({ + oAuthKeyData: { + evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", + Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", + }, + finalKeyData: { + evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", + Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", + }, + metadata: { + pubNonce: { + X: "d6404befc44e3ab77a8387829d77e9c77a9c2fb37ae314c3a59bdc108d70349d", + Y: "1054dfe297f1d977ccc436109cbcce64e95b27f93efc0f1dab739c9146eda2e", + }, + nonce: new BN("0"), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + + // to do: update pub keys + it.skip("should lookup return hash when verifierID hash enabled", async function () { + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_VERIFIER }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + for (const endpoint of torusNodeEndpoints) { + const pubKeyX = "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a"; + const pubKeyY = "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e"; + const response = await lookupVerifier(endpoint, pubKeyX, pubKeyY); + const verifierID = response.result.verifiers[HashEnabledVerifier][0]; + expect(verifierID).to.equal("086c23ab78578f2fce9a1da11c0071ec7c2225adb1bf499ffaee98675bee29b7"); + } + }); + + it("should fetch user type and public address when verifierID hash enabled", async function () { + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result).eql({ + oAuthKeyData: { + evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", + Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", + }, + finalKeyData: { + evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", + Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", + }, + metadata: { + pubNonce: { + X: "d6404befc44e3ab77a8387829d77e9c77a9c2fb37ae314c3a59bdc108d70349d", + Y: "1054dfe297f1d977ccc436109cbcce64e95b27f93efc0f1dab739c9146eda2e", + }, + nonce: new BN("0"), + upgraded: false, + typeOfUser: "v2", + }, + nodesData: result.nodesData, + }); + }); + it("should be able to login when verifierID hash enabled", async function () { + const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_TEST_EMAIL }, + token + ); + expect(result.finalKeyData.privKey).to.be.equal("066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32"); + expect(result).eql({ + finalKeyData: { + evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", + Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", + privKey: "066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32", + }, + oAuthKeyData: { + evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", + Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", + privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", + }, + sessionData: { + sessionTokenData: result.sessionData.sessionTokenData, + sessionAuthKey: result.sessionData.sessionAuthKey, + }, + metadata: { + pubNonce: { + X: "d6404befc44e3ab77a8387829d77e9c77a9c2fb37ae314c3a59bdc108d70349d", + Y: "1054dfe297f1d977ccc436109cbcce64e95b27f93efc0f1dab739c9146eda2e", + }, + nonce: new BN("51eb06f7901d5a8562274d3e53437328ca41ad96926f075122f6bd50e31be52d", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); + + it("should be able to aggregate login", async function () { + const email = faker.internet.email(); + const idToken = generateIdToken(email, "ES256"); + const hashedIdToken = keccak256(Buffer.from(idToken, "utf8")); + const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: email }; + + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2) + ); + expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.evmAddress).to.not.equal(""); + expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.metadata.typeOfUser).to.equal("v2"); + expect(result.metadata.nonce).to.not.equal(null); + expect(result.metadata.upgraded).to.equal(false); + }); +}); From d20b635dadc2e7d9e7611dc668195fa61e5210a1 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 12 Dec 2023 19:02:17 +0800 Subject: [PATCH 08/56] skip ed25519 as us region is not updated yet --- test/sapphire_devnet_ed25519.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 948f25f..22c71e7 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -21,7 +21,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe.only("torus utils ed25519 sapphire devnet", function () { +describe.skip("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; From fe96658a224083933f56e51fb690b5fc5066f423 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 13 Dec 2023 02:33:24 +0800 Subject: [PATCH 09/56] tests fixed --- src/helpers/common.ts | 15 ++-- src/helpers/nodeUtils.ts | 4 +- src/loglevel.ts | 2 +- test/aqua.test.ts | 54 ++++++------ test/celeste.test.ts | 2 +- test/cyan.test.ts | 17 ++-- test/mainnet.test.ts | 35 ++++---- test/onekey.test.ts | 2 +- test/sapphire_devnet.test.ts | 120 +++++++++++---------------- test/sapphire_devnet_ed25519.test.ts | 21 ----- 10 files changed, 119 insertions(+), 153 deletions(-) diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 855c195..7d0e07e 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -13,13 +13,14 @@ export const normalizeKeysResult = (result: VerifierLookupResponse) => { is_new_key: result.is_new_key, }; if (result && result.keys && result.keys.length > 0) { - finalResult.keys = result.keys.map((key) => { - return { - pub_key_X: key.pub_key_X, - pub_key_Y: key.pub_key_Y, - address: key.address, - }; - }); + const finalKey = result.keys[0]; + finalResult.keys = [ + { + pub_key_X: finalKey.pub_key_X, + pub_key_Y: finalKey.pub_key_Y, + address: finalKey.address, + }, + ]; } return finalResult; }; diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 6b694d5..61628e6 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -542,8 +542,8 @@ export async function retrieveOrImportShare(params: { if (!privateKey) throw new Error("Invalid private key returned"); const oAuthKey = privateKey; const oAuthPubKey = derivePubKey(ecCurve, oAuthKey); - const oAuthPubkeyX = oAuthPubKey.getX().toString("hex"); - const oAuthPubkeyY = oAuthPubKey.getY().toString("hex"); + const oAuthPubkeyX = oAuthPubKey.getX().toString("hex", 64); + const oAuthPubkeyY = oAuthPubKey.getY().toString("hex", 64); let metadataNonce = new BN(nonceResult?.nonce ? nonceResult.nonce.padStart(64, "0") : "0", "hex"); let finalPubKey: curve.base.BasePoint; diff --git a/src/loglevel.ts b/src/loglevel.ts index d8d3e53..1d33267 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.enableAll(); +log.disableAll(); export default log; diff --git a/test/aqua.test.ts b/test/aqua.test.ts index 4358388..9d35806 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -55,8 +55,7 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = (await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; - expect(result1.finalKeyData.evmAddress).to.equal("0x79F06350eF34Aeed4BE68e26954D405D573f1438"); - expect(result1.metadata.typeOfUser).to.equal("v1"); + expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1).eql({ oAuthKeyData: { evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", @@ -64,15 +63,18 @@ describe("torus utils aqua", function () { Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, finalKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", - X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", - Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", + evmAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438", + X: "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3", + Y: "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "dc5a031fd2e0b55dbaece314ea125bac9da5f0a916bf156ff36b5ad71380ea32", + Y: "affd749b98c209d2f9cf4dacb145d7897f82f1e2924a47b07874302ecc0b8ef1", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result1.nodesData, }); @@ -84,24 +86,26 @@ describe("torus utils aqua", function () { verifier: v2Verifier, verifierId: v2TestEmail, })) as TorusPublicKey; - expect(result2.finalKeyData.evmAddress).to.equal("0x5735dDC8d5125B23d77C3531aab3895A533584a3"); - expect(result2.metadata.typeOfUser).to.equal("v1"); + expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x5735dDC8d5125B23d77C3531aab3895A533584a3", - X: "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873", - Y: "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2", + evmAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828", + X: "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337", + Y: "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d", }, finalKeyData: { - evmAddress: "0x5735dDC8d5125B23d77C3531aab3895A533584a3", - X: "e1b419bc52b82e14b148c307f10479cfa464d20c947555fb4758c586eab12873", - Y: "75f47d7d5a271c0fcf51a790c1683a1cb3394b1d37d20e29c346ac249e3bfca2", + evmAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD", + X: "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022", + Y: "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "1601cf4dc4362b219260663d5ec5119699fbca185d08b7acb2e36cad914340d5", + Y: "c2f7871f61ee71b4486ac9fb40ec759099800e737139dc5dfaaaed8c9d77c3c1", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result2.nodesData, }); @@ -112,8 +116,7 @@ describe("torus utils aqua", function () { verifier: v2Verifier, verifierId: v2nTestEmail, })) as TorusPublicKey; - expect(result3.finalKeyData.evmAddress).to.equal("0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD"); - expect(result3.metadata.typeOfUser).to.equal("v1"); + expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", @@ -121,15 +124,18 @@ describe("torus utils aqua", function () { Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f", }, finalKeyData: { - evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", - X: "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281", - Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f", + evmAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", + X: "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539", + Y: "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "17b1ebce1fa874452a96d0c6d74c1445b78f16957c7decc5d2a202b0ce4662f5", + Y: "b5432cb593753e1b3ecf98b05dc03e57bc02c415e1b80a1ffc5a401ec1f0abd6", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result3.nodesData, }); diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 8644c1e..aeeb05b 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe("torus utils celeste", function () { +describe.only("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; diff --git a/test/cyan.test.ts b/test/cyan.test.ts index a972be0..5d3ec91 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -55,8 +55,8 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0xA3767911A84bE6907f26C572bc89426dDdDB2825"); - expect(result1.metadata.typeOfUser).to.equal("v1"); + expect(result1.finalKeyData.evmAddress).to.equal("0x3507F0d192a44E436B8a6C32a37d57D022861b1a"); + expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1).eql({ oAuthKeyData: { evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", @@ -64,15 +64,18 @@ describe("torus utils cyan", function () { Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, finalKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", - X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", - Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", + evmAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a", + X: "8aaadab9530cb157d0b0dfb7b27d1a3aaca45274563c22c92c77ee2191779051", + Y: "d57b89d9f62bb6609d8542c3057943805c8c72f6f27d39781b820f27d7210f12", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "5f2505155e2c1119ee8a76d0f3b22fccee45871d4aab3cb6209bdbc302b5abc2", + Y: "a20f30868759a6095697d5631483faa650f489b33c0e2958ad8dc29e707c0a99", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result1.nodesData, }); diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index 07ab1cc..1a94a19 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -55,8 +55,7 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A"); - expect(result1.metadata.typeOfUser).to.equal("v1"); + expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1).eql({ oAuthKeyData: { evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", @@ -64,15 +63,18 @@ describe("torus utils mainnet", function () { Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, finalKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", - X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", - Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", + evmAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", + X: "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55", + Y: "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "eb22d93244acf7fcbeb6566da722bc9c8e5433cd28da25ca0650d9cb32806c39", + Y: "765541e214f067cfc44dcf41e582ae09b71c2e607a301cc8a45e1f316a6ba91c", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result1.nodesData, }); @@ -115,8 +117,7 @@ describe("torus utils mainnet", function () { verifier: v2Verifier, verifierId: v2nTestEmail, }); - expect(result3.finalKeyData.evmAddress).to.equal("0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53"); - expect(result3.metadata.typeOfUser).to.equal("v1"); + expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", @@ -124,15 +125,18 @@ describe("torus utils mainnet", function () { Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7", }, finalKeyData: { - evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", - X: "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8", - Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7", + evmAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", + X: "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc", + Y: "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff", }, metadata: { - pubNonce: undefined, + pubNonce: { + X: "16214bf232167258fb5f98fa9d84968ffec3236aaf0994fc366940c4bc07a5b1", + Y: "475e8c09d2cc8f6c12a767f51c052b1bf8e8d3a2a2b6818d4b199dc283e80ac4", + }, nonce: new BN(0), upgraded: false, - typeOfUser: "v1", + typeOfUser: "v2", }, nodesData: result3.nodesData, }); @@ -159,9 +163,6 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token); - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x90A926b698047b4A87265ba1E9D8b512E8489067"); - expect(result.finalKeyData.privKey).to.be.equal("0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x90A926b698047b4A87265ba1E9D8b512E8489067"); delete result.sessionData; expect(result).eql({ diff --git a/test/onekey.test.ts b/test/onekey.test.ts index bc59411..ea38d68 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -15,7 +15,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe("torus onekey", function () { +describe.skip("torus onekey", function () { let torus: TorusUtils; beforeEach("one time execution before all tests", async function () { diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index f43344e..24d5997 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -9,7 +9,9 @@ import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; -const TORUS_TEST_EMAIL = "saasas@tr.us"; +const TORUS_TEST_EMAIL = "devnettestuser@tor.us"; +const TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us"; + const TORUS_IMPORT_EMAIL = "Elena_Hermann@yahoo.com"; const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"; @@ -201,22 +203,21 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0x4924F91F5d6701dDd41042D94832bB17B76F316F"); expect(result).eql({ oAuthKeyData: { - evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", - X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", - Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", + evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", - X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", - Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", + evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, metadata: { pubNonce: { - X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", - Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", }, nonce: new BN("0"), upgraded: false, @@ -226,7 +227,7 @@ describe("torus utils sapphire devnet", function () { }); }); // we are working on a new implementation for import sss keys, so skipping it for now. - it.skip("should fetch public address of imported user", async function () { + it("should fetch public address of imported user", async function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; @@ -257,22 +258,21 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0x4924F91F5d6701dDd41042D94832bB17B76F316F"); expect(result).eql({ oAuthKeyData: { - evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", - X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", - Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", + evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", - X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", - Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", + evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, metadata: { pubNonce: { - X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", - Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", }, nonce: new BN("0"), upgraded: false, @@ -303,19 +303,18 @@ describe("torus utils sapphire devnet", function () { { verifier_id: TORUS_TEST_EMAIL }, token ); - expect(result.finalKeyData.privKey).to.be.equal("04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c"); expect(result).eql({ finalKeyData: { - evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", - X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", - Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", - privKey: "04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c", + evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", + privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", - X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", - Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", - privKey: "cd7d1dc7aec71fd2ee284890d56ac34d375bbc15ff41a1d87d088170580b9b0f", + evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, @@ -323,10 +322,10 @@ describe("torus utils sapphire devnet", function () { }, metadata: { pubNonce: { - X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", - Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", }, - nonce: new BN("376df8a62e2e72a2b3e87e97c85f86b3f2dac41082ddeb863838d80462deab5e", "hex"), + nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), typeOfUser: "v2", upgraded: false, }, @@ -346,19 +345,18 @@ describe("torus utils sapphire devnet", function () { { verifier_id: TORUS_TEST_EMAIL }, token ); - expect(result.finalKeyData.privKey).to.be.equal("04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c"); expect(result).eql({ finalKeyData: { - evmAddress: "0x4924F91F5d6701dDd41042D94832bB17B76F316F", - X: "f3eaf63bf1fd645d4159832ccaad7f42457e287ac929363ba636eb7e87978bff", - Y: "f3b9d8dd91927a89ec45199ad697fe3fa01b8b836710143a0babb1a4eb35f1cd", - privKey: "04eb166ddcf59275a210c7289dca4a026f87a33fd2d6ed22f56efae7eab4052c", + evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", + Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", + privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0xac997dE675Fb69FCb0F4115A23c0061A892A2772", - X: "9508a251dfc4146a132feb96111c136538f4fabd20fc488dbcaaf762261c1528", - Y: "f9128bc7403bab6d45415cad01dd0ba0924628cfb6bf51c17e77aa8ca43b3cfe", - privKey: "cd7d1dc7aec71fd2ee284890d56ac34d375bbc15ff41a1d87d088170580b9b0f", + evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, @@ -366,10 +364,10 @@ describe("torus utils sapphire devnet", function () { }, metadata: { pubNonce: { - X: "78a88b99d960808543e75076529c913c1678bc7fafbb943f1ce58235fd2f4e0c", - Y: "6b451282135dfacd22561e0fb5bf21aea7b1f26f2442164b82b0e4c8f152f7a7", + X: "5d03a0df9b3db067d3363733df134598d42873bb4730298a53ee100975d703cc", + Y: "279434dcf0ff22f077877a70bcad1732412f853c96f02505547f7ca002b133ed", }, - nonce: new BN("376df8a62e2e72a2b3e87e97c85f86b3f2dac41082ddeb863838d80462deab5e", "hex"), + nonce: new BN("b7d126751b68ecd09e371a23898e6819dee54708a5ead4f6fe83cdc79c0f1c4a", "hex"), typeOfUser: "v2", upgraded: false, }, @@ -396,27 +394,6 @@ describe("torus utils sapphire devnet", function () { const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, verifierId: email }); expect(result1.finalKeyData.evmAddress).to.be.equal(result.finalKeyData.evmAddress); }); - it("should be able to import a key for a existing user", async function () { - let verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const token = generateIdToken(TORUS_IMPORT_EMAIL, "ES256"); - const privKeyBuffer = generatePrivate(); - const privHex = privKeyBuffer.toString("hex"); - const result1 = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_IMPORT_EMAIL }, - token, - privHex - ); - expect(result1.finalKeyData.privKey).to.be.equal(privHex); - verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; - const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.be.equal(result2.finalKeyData.evmAddress); - }); it("should fetch pub address of tss verifier id", async function () { const email = TORUS_EXTENDED_VERIFIER_EMAIL; @@ -427,7 +404,6 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.be.equal("0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30"); expect(result).eql({ oAuthKeyData: { evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", @@ -487,7 +463,7 @@ describe("torus utils sapphire devnet", function () { }); it("should fetch public address when verifierID hash enabled", async function () { - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); @@ -518,7 +494,7 @@ describe("torus utils sapphire devnet", function () { // to do: update pub keys it.skip("should lookup return hash when verifierID hash enabled", async function () { - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_VERIFIER }); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; for (const endpoint of torusNodeEndpoints) { const pubKeyX = "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a"; @@ -530,7 +506,7 @@ describe("torus utils sapphire devnet", function () { }); it("should fetch user type and public address when verifierID hash enabled", async function () { - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); @@ -559,8 +535,8 @@ describe("torus utils sapphire devnet", function () { }); }); it("should be able to login when verifierID hash enabled", async function () { - const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const token = generateIdToken(TORUS_HASH_ENABLED_TEST_EMAIL, "ES256"); + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_HASH_ENABLED_TEST_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; @@ -568,7 +544,7 @@ describe("torus utils sapphire devnet", function () { torusNodeEndpoints, nodeDetails.torusIndexes, HashEnabledVerifier, - { verifier_id: TORUS_TEST_EMAIL }, + { verifier_id: TORUS_HASH_ENABLED_TEST_EMAIL }, token ); expect(result.finalKeyData.privKey).to.be.equal("066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32"); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 22c71e7..902b80a 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -177,27 +177,6 @@ describe.skip("torus utils ed25519 sapphire devnet", function () { ); expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); }); - it("should be able to import a key for a existing user", async function () { - let verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const token = generateIdToken(TORUS_IMPORT_EMAIL, "ES256"); - const privKeyBuffer = new BN(generatePrivate()).umod(ec.curve.n); - const privHex = privKeyBuffer.toString("hex", 64); - const result1 = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_IMPORT_EMAIL }, - token, - privHex - ); - expect(result1.finalKeyData.privKey).to.be.equal(privHex); - verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; - const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.be.equal(result2.finalKeyData.evmAddress); - }); it("should fetch pub address of tss verifier id", async function () { const email = TORUS_EXTENDED_VERIFIER_EMAIL; From 6760d857aa4228e39d1ce6b6328ce9f1c9723043 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 21 Dec 2023 15:41:53 +0800 Subject: [PATCH 10/56] add method to login with non dkg keys --- src/helpers/common.ts | 8 +++ src/helpers/keyUtils.ts | 63 +++++++++++++++++++++ src/helpers/metadataUtils.ts | 29 +++++++++- src/helpers/nodeUtils.ts | 104 ++++++++++++++++++++++++++++------- src/interfaces.ts | 1 + src/torus.ts | 96 +++++++------------------------- test/celeste.test.ts | 2 +- test/sapphire_devnet.test.ts | 46 +++++++++++++++- 8 files changed, 248 insertions(+), 101 deletions(-) diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 7d0e07e..1674dd5 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -2,6 +2,7 @@ import { Ecies } from "@toruslabs/eccrypto"; import JsonStringify from "json-stable-stringify"; import { EciesHex, VerifierLookupResponse } from "../interfaces"; +import { keccak256 } from "."; // this function normalizes the result from nodes before passing the result to threshold check function // For ex: some fields returns by nodes might be different from each other @@ -84,3 +85,10 @@ export function encParamsHexToBuf(eciesData: Omit): Omit mac: Buffer.from(eciesData.mac, "hex"), }; } + +export function getProxyCoordinatorEndpointIndex(endpoints: string[], verifier: string, verifierId: string) { + const verifierIdStr = `${verifier}${verifierId}`; + const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); + const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; + return proxyEndpointNum; +} diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 16cc029..0ff1237 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,8 +1,13 @@ +import { INodePub } from "@toruslabs/constants"; +import { Ecies, encrypt, generatePrivate } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; +import stringify from "json-stable-stringify"; +import { ImportedShare, KeyType } from ".."; import log from "../loglevel"; +import { encParamsBufToHex, generateNonceMetadataParams, generateRandomPolynomial } from "."; export function keccak256(a: Buffer): string { const hash = Buffer.from(keccakHash(a)).toString("hex"); @@ -59,3 +64,61 @@ export function derivePubKey(ecCurve: EC, sk: BN): curve.base.BasePoint { } export const encryptionEC = new EC("secp256k1"); + +export const generateShares = async ( + ecCurve: EC, + keyType: KeyType, + serverTimeOffset: number, + nodeIndexes: number[], + nodePubkeys: INodePub[], + privKey: string +) => { + const key = ecCurve.keyFromPrivate(privKey.padStart(64, "0"), "hex"); + + const threshold = ~~(nodePubkeys.length / 2) + 1; + const degree = threshold - 1; + const nodeIndexesBn: BN[] = []; + + for (const nodeIndex of nodeIndexes) { + nodeIndexesBn.push(new BN(nodeIndex)); + } + const privKeyBn = key.getPrivate(); + const randomNonce = new BN(generatePrivate()).umod(ecCurve.curve.n); + const oAuthKey = privKeyBn.sub(randomNonce).umod(ecCurve.curve.n); + const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); + const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); + const shares = poly.generateShares(nodeIndexesBn); + const nonceParams = generateNonceMetadataParams(ecCurve, serverTimeOffset, "getOrSetNonce", oAuthKey, keyType, randomNonce); + const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); + const sharesData: ImportedShare[] = []; + const encPromises: Promise[] = []; + for (let i = 0; i < nodeIndexesBn.length; i++) { + const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; + if (!nodePubkeys[i]) { + throw new Error(`Missing node pub key for node index: ${nodeIndexesBn[i].toString("hex", 64)}`); + } + const nodePubKey = encryptionEC.keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); + encPromises.push( + encrypt(Buffer.from(nodePubKey.getPublic().encodeCompressed("hex"), "hex"), Buffer.from(shareJson.share.padStart(64, "0"), "hex")) + ); + } + const encShares = await Promise.all(encPromises); + for (let i = 0; i < nodeIndexesBn.length; i++) { + const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; + const encParams = encShares[i]; + const encParamsMetadata = encParamsBufToHex(encParams); + const shareData: ImportedShare = { + pub_key_x: oAuthPubKey.getX().toString("hex", 64), + pub_key_y: oAuthPubKey.getY().toString("hex", 64), + encrypted_share: encParamsMetadata.ciphertext, + encrypted_share_metadata: encParamsMetadata, + node_index: Number.parseInt(shareJson.shareIndex, 16), + key_type: keyType, + nonce_data: nonceData, + nonce_signature: nonceParams.signature, + }; + sharesData.push(shareData); + } + + return sharesData; +}; diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 99dafd2..bc221c4 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -5,7 +5,7 @@ import { ec } from "elliptic"; import stringify from "json-stable-stringify"; import log from "loglevel"; -import { EciesHex, GetOrSetNonceResult, KeyType, MetadataParams } from "../interfaces"; +import { EciesHex, GetOrSetNonceResult, KeyType, MetadataParams, NonceMetadataParams, SetNonceData } from "../interfaces"; import { encParamsHexToBuf } from "./common"; import { keccak256 } from "./keyUtils"; @@ -93,3 +93,30 @@ export async function getNonce( ): Promise { return getOrSetNonce(legacyMetadataHost, ecCurve, keyType, serverTimeOffset, X, Y, privKey, true); } + +export function generateNonceMetadataParams( + ecCurve: ec, + serverTimeOffset: number, + operation: string, + privateKey: BN, + keyType: KeyType, + nonce?: BN +): NonceMetadataParams { + const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); + const setData: Partial = { + operation, + timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), + }; + + if (nonce) { + setData.data = nonce.toString("hex", 64); + } + const sig = key.sign(keccak256(Buffer.from(stringify(setData), "utf8")).slice(2)); + return { + pub_key_X: key.getPublic().getX().toString("hex", 64), + pub_key_Y: key.getPublic().getY().toString("hex", 64), + set_data: setData, + key_type: keyType, + signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), + }; +} diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 61628e6..3a54b56 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -1,4 +1,4 @@ -import { LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; @@ -28,8 +28,8 @@ import { } from "../interfaces"; import log from "../loglevel"; import { Some } from "../some"; -import { kCombinations, normalizeKeysResult, thresholdSame } from "./common"; -import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils"; +import { getProxyCoordinatorEndpointIndex, kCombinations, normalizeKeysResult, thresholdSame } from "./common"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generateShares, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -126,10 +126,14 @@ export async function retrieveOrImportShare(params: { network: string; clientId: string; endpoints: string[]; + indexes: number[]; verifier: string; verifierParams: VerifierParams; idToken: string; - importedShares?: ImportedShare[]; + useDkg: boolean; + overrideExistingKey: boolean; + nodePubkeys: INodePub[]; + newImportedShares?: ImportedShare[]; extraParams: Record; }): Promise { const { @@ -142,11 +146,15 @@ export async function retrieveOrImportShare(params: { network, clientId, endpoints, + nodePubkeys, + indexes, verifier, verifierParams, idToken, - importedShares, + overrideExistingKey, + newImportedShares, extraParams, + useDkg = true, } = params; await get( allowHost, @@ -169,12 +177,17 @@ export async function retrieveOrImportShare(params: { const pubKeyX = pubKey.slice(2, 66); const pubKeyY = pubKey.slice(66); const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); - let isImportShareReq = false; - if (importedShares && importedShares.length > 0) { - if (importedShares.length !== endpoints.length) { + let finalImportedShares: ImportedShare[] = []; + + if (newImportedShares.length > 0) { + if (newImportedShares.length !== endpoints.length) { throw new Error("Invalid imported shares length"); } - isImportShareReq = true; + finalImportedShares = newImportedShares; + } else if (!useDkg) { + const importedKey = new BN(generatePrivate()).umod(ecCurve.curve.n); + const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey.toString(16, 64)); + finalImportedShares = [...finalImportedShares, ...generatedShares]; } // make commitment requests to endpoints @@ -197,6 +210,8 @@ export async function retrieveOrImportShare(params: { temppubx: pubKeyX, temppuby: pubKeyY, verifieridentifier: verifier, + verifier_id: verifierParams.verifier_id, + is_import_key_flow: true, }), null, { logTracingHeader: config.logRequestTracing } @@ -217,17 +232,60 @@ export async function retrieveOrImportShare(params: { return true; }); - // we need to get commitments from all endpoints for importing share - if (importedShares.length > 0 && completedRequests.length === endpoints.length) { - return Promise.resolve(resultArr); - } else if (importedShares.length === 0 && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + if (finalImportedShares.length > 0) { + // this case is for imported keys + // for imported keys registration we need to wait for all nodes to agree on commitment + // for existing imported keys we can rely on threshold nodes commitment + if (overrideExistingKey && completedRequests.length === endpoints.length) { + const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { + if (resp && resp.result?.nodeindex === "1") { + return true; + } + return false; + }); + if (requiredNodeResult) { + return Promise.resolve(resultArr); + } + } else if (!overrideExistingKey && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + // for import shares, proxy node response is required. + // proxy node returns metadata unlike dkg keys where node 1 is checked for metadata. + // if user's account already + const nodeSigs: CommitmentRequestResult[] = []; + for (let i = 0; i < completedRequests.length; i += 1) { + const x = completedRequests[i]; + if (!x || typeof x !== "object" || x.error) { + continue; + } + if (x) nodeSigs.push((x as JRPCResponse).result); + } + const existingPubKey = thresholdSame( + nodeSigs.map((x) => x && x.pub_key_x), + ~~(endpoints.length / 2) + 1 + ); + const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); + const requiredNodeIndex = indexes[proxyEndpointNum].toString(10); + + // if not a existing key we need to wait for nodes to agree on commitment + if (existingPubKey || (!existingPubKey && completedRequests.length === endpoints.length)) { + const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { + if (resp && resp.result?.nodeindex === requiredNodeIndex) { + return true; + } + return false; + }); + if (requiredNodeResult) { + return Promise.resolve(resultArr); + } + } + } + } else if (completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + // this case is for dkg keys const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { if (resp && resp.result?.nodeindex === "1") { return true; } return false; }); - if (requiredNodeResult) { return Promise.resolve(resultArr); } @@ -246,17 +304,23 @@ export async function retrieveOrImportShare(params: { if (x) nodeSigs.push((x as JRPCResponse).result); } - if (isImportShareReq) { - const verifierIdStr = `${verifier}${verifierParams.verifier_id}`; - const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); - const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; + // if user's account already + const existingPubKey = thresholdSame( + nodeSigs.map((x) => x && x.pub_key_x), + ~~(endpoints.length / 2) + 1 + ); + + // can only import shares if override existing key is allowed or for new non dkg registration + const canImportedShares = overrideExistingKey || (!useDkg && !existingPubKey); + if (canImportedShares) { + const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); const items: Record[] = []; for (let i = 0; i < endpoints.length; i += 1) { const x = responses[i]; if (!x || typeof x !== "object" || x.error) { continue; } - const importedShare = importedShares[i]; + const importedShare = finalImportedShares[i]; items.push({ ...verifierParams, idtoken: idToken, @@ -376,7 +440,7 @@ export async function retrieveOrImportShare(params: { ); } - const thresholdReqCount = importedShares.length > 0 ? endpoints.length : ~~(endpoints.length / 2) + 1; + const thresholdReqCount = ~~(endpoints.length / 2) + 1; // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key diff --git a/src/interfaces.ts b/src/interfaces.ts index dfea815..981d999 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -62,6 +62,7 @@ export interface CommitmentRequestResult { nodepubx: string; nodepuby: string; nodeindex: string; + pub_key_x: string; } export interface JRPCResponse { diff --git a/src/torus.ts b/src/torus.ts index e2668bb..59ba7c6 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -7,20 +7,17 @@ import { TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, } from "@toruslabs/constants"; -import { decrypt, Ecies, encrypt, generatePrivate, getPublic } from "@toruslabs/eccrypto"; +import { decrypt, generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post, setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; -import stringify from "json-stable-stringify"; import { config } from "./config"; import { derivePubKey, - encParamsBufToHex, - encryptionEC, generateAddressFromPrivKey, generateAddressFromPubKey, - generateRandomPolynomial, + generateShares, getMetadata, getNonce, getOrSetNonce, @@ -38,12 +35,9 @@ import { import { CommitmentRequestResult, GetOrSetNonceResult, - ImportedShare, KeyType, LegacyShareRequestResult, LegacyVerifierLookupResponse, - NonceMetadataParams, - SetNonceData, TorusCtorOptions, TorusKey, TorusPublicKey, @@ -136,9 +130,14 @@ class Torus { verifier: string, verifierParams: VerifierParams, idToken: string, - extraParams: Record = {} + nodePubkeys: INodePub[] = [], + extraParams: Record = {}, + useDkg = true ): Promise { if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this._keyType, extraParams); + if (!useDkg && nodePubkeys.length === 0) { + throw new Error("nodePubkeys param is required is useDkg is set to false"); + } return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -149,10 +148,14 @@ class Torus { network: this.network, clientId: this.clientId, endpoints, + indexes, verifier, verifierParams, idToken, - importedShares: [], + useDkg, + newImportedShares: [], + overrideExistingKey: false, + nodePubkeys, extraParams, }); } @@ -180,52 +183,7 @@ class Torus { if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const threshold = ~~(endpoints.length / 2) + 1; - const degree = threshold - 1; - const nodeIndexesBn: BN[] = []; - - const key = this.ec.keyFromPrivate(newPrivateKey.padStart(64, "0"), "hex"); - for (const nodeIndex of nodeIndexes) { - nodeIndexesBn.push(new BN(nodeIndex)); - } - const privKeyBn = key.getPrivate(); - const randomNonce = new BN(generatePrivate()).umod(this.ec.curve.n); - - const oAuthKey = privKeyBn.sub(randomNonce).umod(this.ec.curve.n); - const oAuthPubKey = this.ec.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); - const poly = generateRandomPolynomial(this.ec, degree, oAuthKey); - const shares = poly.generateShares(nodeIndexesBn); - const nonceParams = this.generateNonceMetadataParams("getOrSetNonce", oAuthKey, this._keyType, randomNonce); - const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); - const sharesData: ImportedShare[] = []; - const encPromises: Promise[] = []; - for (let i = 0; i < nodeIndexesBn.length; i++) { - const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; - if (!nodePubkeys[i]) { - throw new Error(`Missing node pub key for node index: ${nodeIndexesBn[i].toString("hex", 64)}`); - } - const nodePubKey = encryptionEC.keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); - encPromises.push( - encrypt(Buffer.from(nodePubKey.getPublic().encodeCompressed("hex"), "hex"), Buffer.from(shareJson.share.padStart(64, "0"), "hex")) - ); - } - const encShares = await Promise.all(encPromises); - for (let i = 0; i < nodeIndexesBn.length; i++) { - const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; - const encParams = encShares[i]; - const encParamsMetadata = encParamsBufToHex(encParams); - const shareData: ImportedShare = { - pub_key_x: oAuthPubKey.getX().toString("hex", 64), - pub_key_y: oAuthPubKey.getY().toString("hex", 64), - encrypted_share: encParamsMetadata.ciphertext, - encrypted_share_metadata: encParamsMetadata, - node_index: Number.parseInt(shareJson.shareIndex, 16), - key_type: this._keyType, - nonce_data: nonceData, - nonce_signature: nonceParams.signature, - }; - sharesData.push(shareData); - } + const sharesData = await generateShares(this.ec, this._keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, newPrivateKey); return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, @@ -237,10 +195,14 @@ class Torus { network: this.network, clientId: this.clientId, endpoints, + indexes: nodeIndexes, verifier, verifierParams, idToken, - importedShares: sharesData, + useDkg: false, + overrideExistingKey: true, + newImportedShares: sharesData, + nodePubkeys, extraParams, }); } @@ -608,26 +570,6 @@ class Torus { throw new Error(`node results do not match at final lookup ${JSON.stringify(keyResult || {})}, ${JSON.stringify(errorResult || {})}`); } - private generateNonceMetadataParams(operation: string, privateKey: BN, keyType: KeyType, nonce?: BN): NonceMetadataParams { - const key = this.ec.keyFromPrivate(privateKey.toString("hex", 64)); - const setData: Partial = { - operation, - timestamp: new BN(~~(this.serverTimeOffset + Date.now() / 1000)).toString(16), - }; - - if (nonce) { - setData.data = nonce.toString("hex", 64); - } - const sig = key.sign(keccak256(Buffer.from(stringify(setData), "utf8")).slice(2)); - return { - pub_key_X: key.getPublic().getX().toString("hex", 64), - pub_key_Y: key.getPublic().getY().toString("hex", 64), - set_data: setData, - key_type: keyType, - signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), - }; - } - private async getNewPublicAddress( endpoints: string[], { verifier, verifierId, extendedVerifierId }: { verifier: string; verifierId: string; extendedVerifierId?: string }, diff --git a/test/celeste.test.ts b/test/celeste.test.ts index aeeb05b..8644c1e 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe.only("torus utils celeste", function () { +describe("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 24d5997..e663875 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -12,7 +12,7 @@ import { generateIdToken, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "devnettestuser@tor.us"; const TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us"; -const TORUS_IMPORT_EMAIL = "Elena_Hermann@yahoo.com"; +const TORUS_IMPORT_EMAIL = "Sydnie.Lehner73@yahoo.com"; const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"; @@ -21,7 +21,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe("torus utils sapphire devnet", function () { +describe.only("torus utils sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -333,6 +333,48 @@ describe("torus utils sapphire devnet", function () { }); }); + it("should be able to login with non dkg keys", async function () { + const email = `atomicimporttest2`; + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ); + + const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.X).eql(publicResult.finalKeyData.X); + }); + + it("should be able to login a new user with non dkg keys", async function () { + const email = `${faker.internet.email()}`; + const token = generateIdToken(email, "ES256"); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ); + + const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + + expect(result.finalKeyData.X).eql(publicResult.finalKeyData.X); + }); it("should be able to login even when node is down", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); From 0b9aff186b11297ea8dfb5df295a70082d1b5be6 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 21 Dec 2023 15:58:18 +0800 Subject: [PATCH 11/56] fix review comments --- src/Point.ts | 6 +++++- src/Share.ts | 4 ++-- src/helpers/common.ts | 3 ++- src/torus.ts | 10 +++++----- test/sapphire_devnet.test.ts | 3 +-- test/sapphire_devnet_ed25519.test.ts | 1 - 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Point.ts b/src/Point.ts index 8f8d91b..1c7f51f 100644 --- a/src/Point.ts +++ b/src/Point.ts @@ -19,7 +19,11 @@ class Point { encode(enc: string): Buffer { switch (enc) { case "arr": - return Buffer.concat([Buffer.from("04", "hex"), Buffer.from(this.x.toString("hex"), "hex"), Buffer.from(this.y.toString("hex"), "hex")]); + return Buffer.concat([ + Buffer.from("04", "hex"), + Buffer.from(this.x.toString("hex", 64), "hex"), + Buffer.from(this.y.toString("hex", 64), "hex"), + ]); case "elliptic-compressed": { const key = this.ecCurve.keyFromPublic({ x: this.x.toString("hex", 64), y: this.y.toString("hex", 64) }, "hex"); return Buffer.from(key.getPublic(true, "hex")); diff --git a/src/Share.ts b/src/Share.ts index 86df11f..a048949 100644 --- a/src/Share.ts +++ b/src/Share.ts @@ -19,8 +19,8 @@ class Share { toJSON(): StringifiedType { return { - share: this.share.toString("hex"), - shareIndex: this.shareIndex.toString("hex"), + share: this.share.toString("hex", 64), + shareIndex: this.shareIndex.toString("hex", 64), }; } } diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 1674dd5..8571538 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -1,4 +1,5 @@ import { Ecies } from "@toruslabs/eccrypto"; +import { BN } from "bn.js"; import JsonStringify from "json-stable-stringify"; import { EciesHex, VerifierLookupResponse } from "../interfaces"; @@ -89,6 +90,6 @@ export function encParamsHexToBuf(eciesData: Omit): Omit export function getProxyCoordinatorEndpointIndex(endpoints: string[], verifier: string, verifierId: string) { const verifierIdStr = `${verifier}${verifierId}`; const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); - const proxyEndpointNum = parseInt(hashedVerifierId, 16) % endpoints.length; + const proxyEndpointNum = new BN(hashedVerifierId, "hex").mod(new BN(endpoints.length)).toNumber(); return proxyEndpointNum; } diff --git a/src/torus.ts b/src/torus.ts index 59ba7c6..f3a8d84 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -256,7 +256,7 @@ class Torus { // generate temporary private and public key that is used to secure receive shares const tmpKey = generatePrivate(); - const pubKey = getPublic(tmpKey).toString("hex"); + const pubKey = getPublic(tmpKey).toString("hex", 64); const pubKeyX = pubKey.slice(2, 66); const pubKeyY = pubKey.slice(66); const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); @@ -431,8 +431,8 @@ class Torus { if (!oAuthKey) throw new Error("Invalid private key returned"); const oAuthPubKey = derivePubKey(this.ec, oAuthKey); - const oAuthKeyX = oAuthPubKey.getX().toString("hex"); - const oAuthKeyY = oAuthPubKey.getY().toString("hex"); + const oAuthKeyX = oAuthPubKey.getX().toString("hex", 64); + const oAuthKeyY = oAuthPubKey.getY().toString("hex", 64); let metadataNonce: BN; let finalPubKey: curve.base.BasePoint; @@ -456,13 +456,13 @@ class Torus { // for imported keys in legacy networks metadataNonce = await getMetadata(this.legacyMetadataHost, { pub_key_X: oAuthKeyX, pub_key_Y: oAuthKeyY }); const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(this.ec.curve.n); - finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex"), "hex").getPublic(); + finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex", 64), "hex").getPublic(); } } else { // for imported keys in legacy networks metadataNonce = await getMetadata(this.legacyMetadataHost, { pub_key_X: oAuthKeyX, pub_key_Y: oAuthKeyY }); const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(this.ec.curve.n); - finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex"), "hex").getPublic(); + finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex", 64), "hex").getPublic(); } const oAuthKeyAddress = generateAddressFromPrivKey(this.ec, oAuthKey); diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index e663875..53fd9f1 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -21,7 +21,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe.only("torus utils sapphire devnet", function () { +describe("torus utils sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -226,7 +226,6 @@ describe.only("torus utils sapphire devnet", function () { nodesData: result.nodesData, }); }); - // we are working on a new implementation for import sss keys, so skipping it for now. it("should fetch public address of imported user", async function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 902b80a..a2188ec 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -97,7 +97,6 @@ describe.skip("torus utils ed25519 sapphire devnet", function () { nodesData: result.nodesData, }); }); - // we are working on a new implementation for import sss keys, so skipping it for now. it("should fetch public address of imported user", async function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); From d9ac9099faff57f37f08568dbc2ca4f9e0ca491a Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 21 Dec 2023 16:02:57 +0800 Subject: [PATCH 12/56] readd one key tests --- test/onekey.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/onekey.test.ts b/test/onekey.test.ts index ea38d68..bc59411 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -15,7 +15,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe.skip("torus onekey", function () { +describe("torus onekey", function () { let torus: TorusUtils; beforeEach("one time execution before all tests", async function () { From 331a9ef5dd7ba80c823fcb0452f95f9b7f909a2d Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 2 Jan 2024 11:45:23 +0530 Subject: [PATCH 13/56] fix generate priv key --- src/helpers/keyUtils.ts | 8 ++++++-- src/helpers/langrangeInterpolatePoly.ts | 18 +++++++++--------- src/helpers/nodeUtils.ts | 4 ++-- src/loglevel.ts | 2 +- test/celeste.test.ts | 4 ++-- test/sapphire_devnet.test.ts | 8 +++++--- test/sapphire_devnet_ed25519.test.ts | 7 +++---- test/sapphire_mainnet.test.ts | 12 ++++++++---- 8 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 0ff1237..32f680e 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,5 +1,5 @@ import { INodePub } from "@toruslabs/constants"; -import { Ecies, encrypt, generatePrivate } from "@toruslabs/eccrypto"; +import { Ecies, encrypt } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; @@ -14,6 +14,10 @@ export function keccak256(a: Buffer): string { return `0x${hash}`; } +export const generatePrivateKey = (ecCurve: EC, buf: typeof Buffer): Buffer => { + return ecCurve.genKeyPair().getPrivate().toArrayLike(buf, "le", 32); +}; + export function stripHexPrefix(str: string): string { return str.startsWith("0x") ? str.slice(2) : str; } @@ -83,7 +87,7 @@ export const generateShares = async ( nodeIndexesBn.push(new BN(nodeIndex)); } const privKeyBn = key.getPrivate(); - const randomNonce = new BN(generatePrivate()).umod(ecCurve.curve.n); + const randomNonce = new BN(generatePrivateKey(ecCurve, Buffer)); const oAuthKey = privKeyBn.sub(randomNonce).umod(ecCurve.curve.n); const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); diff --git a/src/helpers/langrangeInterpolatePoly.ts b/src/helpers/langrangeInterpolatePoly.ts index 4ad7505..28290e6 100644 --- a/src/helpers/langrangeInterpolatePoly.ts +++ b/src/helpers/langrangeInterpolatePoly.ts @@ -1,15 +1,15 @@ -import { generatePrivate } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { ec as EC } from "elliptic"; import Point from "../Point"; import Polynomial from "../Polynomial"; import Share from "../Share"; +import { generatePrivateKey } from "."; -function generatePrivateExcludingIndexes(shareIndexes: BN[]): BN { - const key = new BN(generatePrivate()); +function generatePrivateExcludingIndexes(shareIndexes: BN[], ecCurve: EC): BN { + const key = new BN(generatePrivateKey(ecCurve, Buffer)); if (shareIndexes.find((el) => el.eq(key))) { - return generatePrivateExcludingIndexes(shareIndexes); + return generatePrivateExcludingIndexes(shareIndexes, ecCurve); } return key; } @@ -111,12 +111,12 @@ export function lagrangeInterpolation(ecCurve: EC, shares: BN[], nodeIndex: BN[] export function generateRandomPolynomial(ecCurve: EC, degree: number, secret?: BN, deterministicShares?: Share[]): Polynomial { let actualS = secret; if (!secret) { - actualS = generatePrivateExcludingIndexes([new BN(0)]); + actualS = generatePrivateExcludingIndexes([new BN(0)], ecCurve); } if (!deterministicShares) { const poly = [actualS]; for (let i = 0; i < degree; i += 1) { - const share = generatePrivateExcludingIndexes(poly); + const share = generatePrivateExcludingIndexes(poly, ecCurve); poly.push(share); } return new Polynomial(poly, ecCurve); @@ -133,11 +133,11 @@ export function generateRandomPolynomial(ecCurve: EC, degree: number, secret?: B points[share.shareIndex.toString("hex", 64)] = new Point(share.shareIndex, share.share, ecCurve); }); for (let i = 0; i < degree - deterministicShares.length; i += 1) { - let shareIndex = generatePrivateExcludingIndexes([new BN(0)]); + let shareIndex = generatePrivateExcludingIndexes([new BN(0)], ecCurve); while (points[shareIndex.toString("hex", 64)] !== undefined) { - shareIndex = generatePrivateExcludingIndexes([new BN(0)]); + shareIndex = generatePrivateExcludingIndexes([new BN(0)], ecCurve); } - points[shareIndex.toString("hex", 64)] = new Point(shareIndex, new BN(generatePrivate()).umod(ecCurve.curve.n), ecCurve); + points[shareIndex.toString("hex", 64)] = new Point(shareIndex, new BN(generatePrivateKey(ecCurve, Buffer)), ecCurve); } points["0"] = new Point(new BN(0), actualS, ecCurve); return lagrangeInterpolatePolynomial(ecCurve, Object.values(points)); diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 3a54b56..9573e4e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -29,7 +29,7 @@ import { import log from "../loglevel"; import { Some } from "../some"; import { getProxyCoordinatorEndpointIndex, kCombinations, normalizeKeysResult, thresholdSame } from "./common"; -import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generateShares, keccak256 } from "./keyUtils"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generatePrivateKey, generateShares, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -185,7 +185,7 @@ export async function retrieveOrImportShare(params: { } finalImportedShares = newImportedShares; } else if (!useDkg) { - const importedKey = new BN(generatePrivate()).umod(ecCurve.curve.n); + const importedKey = new BN(generatePrivateKey(ecCurve, Buffer)); const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey.toString(16, 64)); finalImportedShares = [...finalImportedShares, ...generatedShares]; } diff --git a/src/loglevel.ts b/src/loglevel.ts index 1d33267..d8d3e53 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.disableAll(); +log.enableAll(); export default log; diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 8644c1e..32dd741 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe("torus utils celeste", function () { +describe.only("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -149,7 +149,7 @@ describe("torus utils celeste", function () { expect(metadata.upgraded).to.equal(false); }); - it("should be able to login", async function () { + it.only("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 53fd9f1..0593f7f 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -1,11 +1,11 @@ import { TORUS_LEGACY_NETWORK, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import { generatePrivate } from "@toruslabs/eccrypto"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; +import { ec as EC } from "elliptic"; import faker from "faker"; -import { keccak256 } from "../src"; +import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; @@ -418,7 +418,9 @@ describe("torus utils sapphire devnet", function () { it("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); - const privKeyBuffer = generatePrivate(); + const ec = new EC("secp256k1"); + + const privKeyBuffer = generatePrivateKey(ec, Buffer); const privHex = privKeyBuffer.toString("hex"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index a2188ec..8a61300 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -1,12 +1,11 @@ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import { generatePrivate } from "@toruslabs/eccrypto"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; import { ec as EC } from "elliptic"; import faker from "faker"; -import { keccak256 } from "../src"; +import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; @@ -21,7 +20,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe.skip("torus utils ed25519 sapphire devnet", function () { +describe("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -39,7 +38,7 @@ describe.skip("torus utils ed25519 sapphire devnet", function () { it("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); - const privKeyBuffer = new BN(generatePrivate()).umod(ec.curve.n); + const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); const privHex = privKeyBuffer.toString("hex", 64); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index 1a2bddf..e95aac2 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -1,11 +1,11 @@ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import { generatePrivate } from "@toruslabs/eccrypto"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; +import { ec as EC } from "elliptic"; import faker from "faker"; -import { keccak256 } from "../src"; +import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken } from "./helpers"; @@ -61,7 +61,9 @@ describe("torus utils sapphire mainnet", function () { it.skip("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); - const privKeyBuffer = generatePrivate(); + const ec = new EC("secp256k1"); + + const privKeyBuffer = generatePrivateKey(ec, Buffer); const privHex = privKeyBuffer.toString("hex"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; @@ -81,7 +83,9 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const token = generateIdToken(TORUS_IMPORT_EMAIL, "ES256"); - const privKeyBuffer = generatePrivate(); + const ec = new EC("secp256k1"); + + const privKeyBuffer = generatePrivateKey(ec, Buffer); const privHex = privKeyBuffer.toString("hex"); const result1 = await torus.importPrivateKey( torusNodeEndpoints, From c8ed4d4bc50b7ef8632ed67fc534bb5e4b40c0b9 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 2 Jan 2024 12:07:49 +0530 Subject: [PATCH 14/56] fix celeste tests --- src/helpers/nodeUtils.ts | 2 +- src/loglevel.ts | 2 +- src/torus.ts | 5 ++--- test/celeste.test.ts | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 9573e4e..084c37e 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -773,7 +773,7 @@ export const legacyKeyAssign = async ({ const data = generateJsonRPCObject("KeyAssign", { verifier, verifier_id: verifierId.toString(), - key_type: keyType, + // key_type: keyType, // NOTE: key type doesnt work for legacy networks and doesnt have to , so skipping it here. }); try { const signedData = await post( diff --git a/src/loglevel.ts b/src/loglevel.ts index d8d3e53..1d33267 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.enableAll(); +log.disableAll(); export default log; diff --git a/src/torus.ts b/src/torus.ts index f3a8d84..564225d 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -256,7 +256,7 @@ class Torus { // generate temporary private and public key that is used to secure receive shares const tmpKey = generatePrivate(); - const pubKey = getPublic(tmpKey).toString("hex", 64); + const pubKey = getPublic(tmpKey).toString("hex"); const pubKeyX = pubKey.slice(2, 66); const pubKeyY = pubKey.slice(66); const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); @@ -267,14 +267,13 @@ class Torus { endpoints[i], generateJsonRPCObject("CommitmentRequest", { messageprefix: "mug00", - keytype: keyType, tokencommitment: tokenCommitment.slice(2), temppubx: pubKeyX, temppuby: pubKeyY, verifieridentifier: verifier, }) ).catch((err) => { - log.error("commitment", err); + log.error("commitment", err, endpoints[i]); }); promiseArr.push(p); } diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 32dd741..8644c1e 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe.only("torus utils celeste", function () { +describe("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -149,7 +149,7 @@ describe.only("torus utils celeste", function () { expect(metadata.upgraded).to.equal(false); }); - it.only("should be able to login", async function () { + it("should be able to login", async function () { const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); From c70b131b7961039bd141e936b23801df5a60fd1e Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 9 Jan 2024 11:17:43 +0530 Subject: [PATCH 15/56] fix key type --- src/torus.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/torus.ts b/src/torus.ts index 564225d..7ed9660 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -67,7 +67,7 @@ class Torus { private legacyMetadataHost: string; - private _keyType: KeyType = "secp256k1"; + private keyType: KeyType = "secp256k1"; constructor({ enableOneKey = false, @@ -81,8 +81,8 @@ class Torus { if (!clientId) throw Error("Please provide a valid clientId in constructor"); if (!network) throw Error("Please provide a valid network in constructor"); - this._keyType = keyType; - this.ec = new EC(this._keyType); + this.keyType = keyType; + this.ec = new EC(this.keyType); this.serverTimeOffset = serverTimeOffset || 0; // ms this.network = network; this.clientId = clientId; @@ -134,7 +134,7 @@ class Torus { extraParams: Record = {}, useDkg = true ): Promise { - if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this._keyType, extraParams); + if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this.keyType, extraParams); if (!useDkg && nodePubkeys.length === 0) { throw new Error("nodePubkeys param is required is useDkg is set to false"); } @@ -143,7 +143,7 @@ class Torus { serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, - keyType: this._keyType, + keyType: this.keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, @@ -183,14 +183,14 @@ class Torus { if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const sharesData = await generateShares(this.ec, this._keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, newPrivateKey); + const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, newPrivateKey); return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, enableOneKey: this.enableOneKey, ecCurve: this.ec, - keyType: this._keyType, + keyType: this.keyType, allowHost: this.allowHost, network: this.network, clientId: this.clientId, @@ -438,7 +438,7 @@ class Torus { let typeOfUser: UserType = "v1"; let pubKeyNonceResult: { X: string; Y: string } | undefined; if (this.enableOneKey) { - const nonceResult = await getNonce(this.legacyMetadataHost, this.ec, this._keyType, this.serverTimeOffset, oAuthKeyX, oAuthKeyY, oAuthKey); + const nonceResult = await getNonce(this.legacyMetadataHost, this.ec, this.keyType, this.serverTimeOffset, oAuthKeyX, oAuthKeyY, oAuthKey); metadataNonce = new BN(nonceResult.nonce || "0", 16); typeOfUser = nonceResult.typeOfUser; if (typeOfUser === "v2") { @@ -530,7 +530,7 @@ class Torus { let finalKeyResult: LegacyVerifierLookupResponse | undefined; let isNewKey = false; - const { keyResult, errorResult } = (await legacyKeyLookup(endpoints, verifier, verifierId, this._keyType)) || {}; + const { keyResult, errorResult } = (await legacyKeyLookup(endpoints, verifier, verifierId, this.keyType)) || {}; if (errorResult && JSON.stringify(errorResult).includes("Verifier not supported")) { // change error msg throw new Error(`Verifier not supported. Check if you: \n @@ -547,9 +547,9 @@ class Torus { signerHost: this.signerHost, network: this.network, clientId: this.clientId, - keyType: this._keyType, + keyType: this.keyType, }); - const assignResult = await legacyWaitKeyLookup(endpoints, verifier, verifierId, this._keyType, 1000); + const assignResult = await legacyWaitKeyLookup(endpoints, verifier, verifierId, this.keyType, 1000); finalKeyResult = assignResult?.keyResult; isNewKey = true; } else if (keyResult) { @@ -580,7 +580,7 @@ class Torus { network: this.network, verifier, verifierId, - keyType: this._keyType, + keyType: this.keyType, extendedVerifierId, }); const { errorResult, keyResult, nodeIndexes = [] } = keyAssignResult; @@ -685,7 +685,7 @@ class Torus { if (enableOneKey) { try { - nonceResult = await getOrSetNonce(this.legacyMetadataHost, this.ec, this._keyType, this.serverTimeOffset, X, Y, undefined, !isNewKey); + nonceResult = await getOrSetNonce(this.legacyMetadataHost, this.ec, this.keyType, this.serverTimeOffset, X, Y, undefined, !isNewKey); nonce = new BN(nonceResult.nonce || "0", 16); typeOfUser = nonceResult.typeOfUser; } catch { From 119c01cbe905a77caa9c0525bc979be072cb608b Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 15 Jan 2024 12:01:09 +0530 Subject: [PATCH 16/56] make import as default for ed25519 --- src/helpers/common.ts | 2 +- src/torus.ts | 35 +++++++++++++++++++++++----- test/sapphire_devnet_ed25519.test.ts | 19 +++++++++------ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 8571538..affff5b 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -89,7 +89,7 @@ export function encParamsHexToBuf(eciesData: Omit): Omit export function getProxyCoordinatorEndpointIndex(endpoints: string[], verifier: string, verifierId: string) { const verifierIdStr = `${verifier}${verifierId}`; - const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")); + const hashedVerifierId = keccak256(Buffer.from(verifierIdStr, "utf8")).slice(2); const proxyEndpointNum = new BN(hashedVerifierId, "hex").mod(new BN(endpoints.length)).toNumber(); return proxyEndpointNum; } diff --git a/src/torus.ts b/src/torus.ts index 7ed9660..86a3309 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -130,14 +130,37 @@ class Torus { verifier: string, verifierParams: VerifierParams, idToken: string, - nodePubkeys: INodePub[] = [], + nodePubkeys: INodePub[], extraParams: Record = {}, - useDkg = true + useDkg?: boolean ): Promise { - if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this.keyType, extraParams); - if (!useDkg && nodePubkeys.length === 0) { - throw new Error("nodePubkeys param is required is useDkg is set to false"); + if (nodePubkeys.length === 0) { + throw new Error("nodePubkeys param is required"); + } + + if (nodePubkeys.length !== indexes.length) { + throw new Error("nodePubkeys length must be same as indexes length"); + } + + if (nodePubkeys.length !== endpoints.length) { + throw new Error("nodePubkeys length must be same as endpoints length"); } + // dkg is used by default only for secp256k1 keys, + // for ed25519 keys import keys flows is the default + let shouldUseDkg; + if (typeof useDkg === "boolean") { + shouldUseDkg = useDkg; + } else if (this.keyType === "ed25519") { + shouldUseDkg = false; + } else { + shouldUseDkg = true; + } + if (!shouldUseDkg && nodePubkeys.length === 0) { + throw new Error("nodePubkeys param is required"); + } + + if (this.isLegacyNetwork) return this.legacyRetrieveShares(endpoints, indexes, verifier, verifierParams, idToken, this.keyType, extraParams); + return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -152,7 +175,7 @@ class Torus { verifier, verifierParams, idToken, - useDkg, + useDkg: shouldUseDkg, newImportedShares: [], overrideExistingKey: false, nodePubkeys, diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 8a61300..7befc95 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -20,7 +20,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe("torus utils ed25519 sapphire devnet", function () { +describe.only("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -35,7 +35,7 @@ describe("torus utils ed25519 sapphire devnet", function () { TorusUtils.enableLogging(false); }); - it("should be able to import a key for a new user", async function () { + it.only("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); @@ -62,7 +62,8 @@ describe("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, - token + token, + nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); }); @@ -171,7 +172,8 @@ describe("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, - token + token, + nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); }); @@ -234,7 +236,8 @@ describe("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, { extended_verifier_id: tssVerifierId, verifier_id: email }, - token + token, + nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.not.equal(null); expect(result.oAuthKeyData.evmAddress).to.not.equal(null); @@ -324,7 +327,8 @@ describe("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusIndexes, HashEnabledVerifier, { verifier_id: TORUS_TEST_EMAIL }, - token + token, + nodeDetails.torusNodePub ); expect(result).eql({ finalKeyData: { @@ -373,7 +377,8 @@ describe("torus utils ed25519 sapphire devnet", function () { sub_verifier_ids: [TORUS_TEST_VERIFIER], verifier_id: email, }, - hashedIdToken.substring(2) + hashedIdToken.substring(2), + nodeDetails.torusNodePub ); expect(result.finalKeyData.evmAddress).to.not.equal(null); expect(result.finalKeyData.evmAddress).to.not.equal(""); From 52d93e90c1f584bf65689278365af144a2a8e7ca Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 11 Mar 2024 02:03:02 +0530 Subject: [PATCH 17/56] helpers functions to generate ed25519 key data --- src/helpers/keyUtils.ts | 111 ++++++++++++++++++++++++--- src/helpers/nodeUtils.ts | 9 ++- src/interfaces.ts | 10 +++ test/sapphire_devnet_ed25519.test.ts | 14 ++-- 4 files changed, 125 insertions(+), 19 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index f90918a..ddeb7c0 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -3,12 +3,16 @@ import { Ecies, encrypt } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; +import { sha512 } from "ethereum-cryptography/sha512"; import stringify from "json-stable-stringify"; -import { ImportedShare, KeyType } from "../interfaces"; +import { Point } from ".."; +import { ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; import { encParamsBufToHex } from "./common"; import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; import { generateNonceMetadataParams } from "./metadataUtils"; +const ed25519Curve = new EC("ed25519"); +const secp256k1Curve = new EC("secp256k1"); export function keccak256(a: Buffer): string { const hash = Buffer.from(keccakHash(a)).toString("hex"); @@ -16,7 +20,7 @@ export function keccak256(a: Buffer): string { } export const generatePrivateKey = (ecCurve: EC, buf: typeof Buffer): Buffer => { - return ecCurve.genKeyPair().getPrivate().toArrayLike(buf, "le", 32); + return ecCurve.genKeyPair().getPrivate().toArrayLike(buf); }; export function stripHexPrefix(str: string): string { @@ -41,6 +45,97 @@ export function toChecksumAddress(hexAddress: string): string { return ret; } +function adjustScalarBytes(bytes: Buffer): Buffer { + // Section 5: For X25519, in order to decode 32 random bytes as an integer scalar, + // set the three least significant bits of the first byte + bytes[0] &= 248; // 0b1111_1000 + // and the most significant bit of the last to zero, + bytes[31] &= 127; // 0b0111_1111 + // set the second most significant bit of the last byte to 1 + bytes[31] |= 64; // 0b0100_0000 + return bytes; +} + +/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */ +export function getEd25519ExtendedPublicKey(keyHex: BN): { + scalar: BN; + point: Point; +} { + const len = 32; + const G = ed25519Curve.g; + const N = ed25519Curve.n; + const keyBuffer = keyHex.toArrayLike(Buffer); + + if (keyBuffer.length !== 32) { + throw new Error("Invalid seed for ed25519 key derivation"); + } + // Hash private key with curve's hash function to produce uniformingly random input + // Check byte lengths: ensure(64, h(ensure(32, key))) + const hashed = sha512(keyBuffer); + if (hashed.length !== 64) { + throw new Error("Invalid hash length for ed25519 seed"); + } + const head = new BN(adjustScalarBytes(Buffer.from(hashed.slice(0, len)))); + const scalar = new BN(head.umod(N)); // The actual private scalar + const point = G.mul(scalar) as Point; // Point on Edwards curve aka public key + return { scalar, point }; +} + +export const getSecpKeyFromEd25519 = ( + ed25519Scalar: BN +): { + scalar: BN; + point: curve.base.BasePoint; +} => { + const ed25519Key = ed25519Scalar.toString("hex", 64); + const keyHash = keccak256(Buffer.from(ed25519Key, "hex")); + const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n); + const secpKeyPair = secp256k1Curve.keyFromPrivate(secpKey.toString("hex", 64)); + return { + scalar: secpKeyPair.getPrivate(), + point: secpKeyPair.getPublic(), + }; +}; + +export const generateEd25519KeyData = async (ed25519Seed: BN): Promise => { + const finalEd25519Key = getEd25519ExtendedPublicKey(ed25519Seed); + + const encryptionKey = getSecpKeyFromEd25519(finalEd25519Key.scalar); + const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed.toArrayLike(Buffer)); + const encData = { + enc_text: encryptedSeed.ciphertext.toString("hex"), + metadata: encParamsBufToHex(encryptedSeed), + }; + + const encDataBase64 = Buffer.from(JSON.stringify(encData), "utf-8").toString("base64"); + const metadataPrivNonce = ed25519Curve.genKeyPair().getPrivate(); + const oauthKey = finalEd25519Key.scalar.sub(metadataPrivNonce).umod(ed25519Curve.n); + const oauthKeyPair = ed25519Curve.keyFromPrivate(oauthKey.toArrayLike(Buffer)); + return { + oAuthKeyScalar: oauthKeyPair.getPrivate(), + oAuthPubX: oauthKeyPair.getPublic().getX(), + oAuthPubY: oauthKeyPair.getPublic().getY(), + metadataNonce: metadataPrivNonce, + encryptionScalar: encryptionKey.scalar, + encryptedSeed: encDataBase64, + }; +}; + +export const generateSecp256k1KeyData = async (scalar: BN): Promise => { + const key = secp256k1Curve.keyFromPrivate(scalar.toString("hex", 64)); + const randomNonce = new BN(generatePrivateKey(secp256k1Curve, Buffer)); + const oAuthKey = scalar.sub(randomNonce).umod(secp256k1Curve.curve.n); + const oAuthPubKey = secp256k1Curve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); + return { + oAuthKeyScalar: key.getPrivate(), + oAuthPubX: oAuthPubKey.getX(), + oAuthPubY: oAuthPubKey.getY(), + metadataNonce: randomNonce, + encryptedSeed: "", + encryptionScalar: new BN(0), + }; +}; + export function generateAddressFromPrivKey(ecCurve: EC, privateKey: BN): string { const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64), "hex"); const publicKey = key.getPublic().encode("hex", false).slice(2); @@ -74,10 +169,10 @@ export const generateShares = async ( serverTimeOffset: number, nodeIndexes: number[], nodePubkeys: INodePub[], - privKey: string + privKey: BN ) => { - const key = ecCurve.keyFromPrivate(privKey.padStart(64, "0"), "hex"); - + const keyData = keyType === "ed25519" ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); + const { metadataNonce, oAuthKeyScalar: oAuthKey } = keyData; const threshold = ~~(nodePubkeys.length / 2) + 1; const degree = threshold - 1; const nodeIndexesBn: BN[] = []; @@ -85,13 +180,10 @@ export const generateShares = async ( for (const nodeIndex of nodeIndexes) { nodeIndexesBn.push(new BN(nodeIndex)); } - const privKeyBn = key.getPrivate(); - const randomNonce = new BN(generatePrivateKey(ecCurve, Buffer)); - const oAuthKey = privKeyBn.sub(randomNonce).umod(ecCurve.curve.n); const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); const shares = poly.generateShares(nodeIndexesBn); - const nonceParams = generateNonceMetadataParams(ecCurve, serverTimeOffset, "getOrSetNonce", oAuthKey, keyType, randomNonce); + const nonceParams = generateNonceMetadataParams(ecCurve, serverTimeOffset, "getOrSetNonce", oAuthKey, keyType, metadataNonce); const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); const sharesData: ImportedShare[] = []; const encPromises: Promise[] = []; @@ -111,6 +203,7 @@ export const generateShares = async ( const encParams = encShares[i]; const encParamsMetadata = encParamsBufToHex(encParams); const shareData: ImportedShare = { + encrypted_seed: keyData.encryptedSeed, pub_key_x: oAuthPubKey.getX().toString("hex", 64), pub_key_y: oAuthPubKey.getY().toString("hex", 64), encrypted_share: encParamsMetadata.ciphertext, diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 98c9421..5dc29c3 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -208,7 +208,7 @@ export async function retrieveOrImportShare(params: { finalImportedShares = newImportedShares; } else if (!useDkg) { const importedKey = new BN(generatePrivateKey(ecCurve, Buffer)); - const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey.toString(16, 64)); + const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey); finalImportedShares = [...finalImportedShares, ...generatedShares]; } @@ -255,9 +255,9 @@ export async function retrieveOrImportShare(params: { }); if (finalImportedShares.length > 0) { - // this case is for imported keys - // for imported keys registration we need to wait for all nodes to agree on commitment - // for existing imported keys we can rely on threshold nodes commitment + // this is a optimization is for imported keys + // for new imported keys registration we need to wait for all nodes to agree on commitment + // for fetching existing imported keys we can rely on threshold nodes commitment if (overrideExistingKey && completedRequests.length === endpoints.length) { const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { if (resp && resp.result?.nodeindex === "1") { @@ -366,6 +366,7 @@ export async function retrieveOrImportShare(params: { encrypted: "yes", use_temp: true, item: items, + encrypted_seed: items[0]?.encrypted_seed || "", key_type: keyType, one_key_flow: true, }), diff --git a/src/interfaces.ts b/src/interfaces.ts index f3c389a..bac2003 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -165,6 +165,7 @@ export interface ImportedShare { pub_key_y: string; encrypted_share: string; encrypted_share_metadata: EciesHex; + encrypted_seed?: string; node_index: number; key_type: string; nonce_data: string; @@ -241,3 +242,12 @@ export interface MetadataParams { }; signature: string; } + +export interface PrivateKeyData { + oAuthKeyScalar: BN; + oAuthPubX: BN; + oAuthPubY: BN; + metadataNonce: BN; + encryptedSeed?: string; + encryptionScalar?: BN; +} diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index ce354a5..38c7d57 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -5,7 +5,7 @@ import { expect } from "chai"; import { ec as EC } from "elliptic"; import faker from "faker"; -import { generatePrivateKey, keccak256 } from "../src"; +import { generatePrivateKey, getEd25519ExtendedPublicKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; @@ -69,11 +69,13 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); it.only("should fetch public address", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "aslkasakl" }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - console.log("result", result); + const randomKey = ec.genKeyPair(); + getEd25519ExtendedPublicKey(randomKey.getPrivate()); + // const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "aslkasakl" }; + // const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + // const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + // const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + // console.log("result", result); // expect(result.finalKeyData.X).to.equal("3af3d1e4e10d65ddb96210d5865ddab5b7c5fbe2bad157a6497615cfa8e9bcf5"); // expect(result).eql({ // oAuthKeyData: { From 12fb612fbf6f0cc8f0c3a5c3e3b7d14453f874fb Mon Sep 17 00:00:00 2001 From: himanshu Date: Sat, 16 Mar 2024 00:58:51 +0530 Subject: [PATCH 18/56] working ed25519 key pairs --- package-lock.json | 33 ++++++++++----- src/helpers/common.ts | 3 ++ src/helpers/keyUtils.ts | 60 ++++++++++++++++++---------- src/helpers/metadataUtils.ts | 37 ++++++++++++++--- src/helpers/nodeUtils.ts | 32 ++++++++++++--- src/interfaces.ts | 32 ++++++++++++--- src/loglevel.ts | 2 +- src/torus.ts | 24 ++++++++++- test/sapphire_devnet_ed25519.test.ts | 60 ++++++++++++++++------------ 9 files changed, 208 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4246b5a..28fe2fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2303,17 +2303,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@noble/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", - "dependencies": { - "@noble/hashes": "1.3.1" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@noble/hashes": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", @@ -2851,6 +2840,17 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@scure/bip39": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", @@ -6815,6 +6815,17 @@ "@scure/bip39": "1.2.1" } }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 023599a..1dbe0d2 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -1,10 +1,13 @@ import { Ecies } from "@toruslabs/eccrypto"; import { BN } from "bn.js"; +import { ec as EC } from "elliptic"; import JsonStringify from "json-stable-stringify"; import { EciesHex, LegacyVerifierLookupResponse, VerifierLookupResponse } from "../interfaces"; import { keccak256 } from "."; +export const ed25519Curve = new EC("ed25519"); +export const secp256k1Curve = new EC("secp256k1"); // this function normalizes the result from nodes before passing the result to threshold check function // For ex: some fields returns by nodes might be different from each other // like created_at field might vary and nonce_data might not be returned by all nodes because diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index ddeb7c0..4b64973 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -5,14 +5,12 @@ import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import { sha512 } from "ethereum-cryptography/sha512"; import stringify from "json-stable-stringify"; +import log from "loglevel"; -import { Point } from ".."; -import { ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; -import { encParamsBufToHex } from "./common"; +import { EncryptedSeed, ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; +import { ed25519Curve, encParamsBufToHex, secp256k1Curve } from "./common"; import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; import { generateNonceMetadataParams } from "./metadataUtils"; -const ed25519Curve = new EC("ed25519"); -const secp256k1Curve = new EC("secp256k1"); export function keccak256(a: Buffer): string { const hash = Buffer.from(keccakHash(a)).toString("hex"); @@ -59,7 +57,7 @@ function adjustScalarBytes(bytes: Buffer): Buffer { /** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */ export function getEd25519ExtendedPublicKey(keyHex: BN): { scalar: BN; - point: Point; + point: curve.base.BasePoint; } { const len = 32; const G = ed25519Curve.g; @@ -67,6 +65,7 @@ export function getEd25519ExtendedPublicKey(keyHex: BN): { const keyBuffer = keyHex.toArrayLike(Buffer); if (keyBuffer.length !== 32) { + log.error("Invalid seed for ed25519 key derivation", keyBuffer.length); throw new Error("Invalid seed for ed25519 key derivation"); } // Hash private key with curve's hash function to produce uniformingly random input @@ -75,9 +74,9 @@ export function getEd25519ExtendedPublicKey(keyHex: BN): { if (hashed.length !== 64) { throw new Error("Invalid hash length for ed25519 seed"); } - const head = new BN(adjustScalarBytes(Buffer.from(hashed.slice(0, len)))); - const scalar = new BN(head.umod(N)); // The actual private scalar - const point = G.mul(scalar) as Point; // Point on Edwards curve aka public key + const head = new BN(adjustScalarBytes(Buffer.from(hashed.slice(0, len))), "le"); + const scalar = new BN(head.umod(N), "le"); // The actual private scalar + const point = G.mul(scalar) as curve.base.BasePoint; // Point on Edwards curve aka public key return { scalar, point }; } @@ -88,7 +87,7 @@ export const getSecpKeyFromEd25519 = ( point: curve.base.BasePoint; } => { const ed25519Key = ed25519Scalar.toString("hex", 64); - const keyHash = keccak256(Buffer.from(ed25519Key, "hex")); + const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n); const secpKeyPair = secp256k1Curve.keyFromPrivate(secpKey.toString("hex", 64)); return { @@ -97,14 +96,21 @@ export const getSecpKeyFromEd25519 = ( }; }; +export function encodeEd25519Point(point: curve.base.BasePoint) { + const encodingLength = Math.ceil(ed25519Curve.n.bitLength() / 8); + const enc = point.getY().toArrayLike(Buffer, "le", encodingLength); + enc[encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; + return enc; +} + export const generateEd25519KeyData = async (ed25519Seed: BN): Promise => { const finalEd25519Key = getEd25519ExtendedPublicKey(ed25519Seed); - const encryptionKey = getSecpKeyFromEd25519(finalEd25519Key.scalar); const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed.toArrayLike(Buffer)); - const encData = { + const encData: EncryptedSeed = { enc_text: encryptedSeed.ciphertext.toString("hex"), metadata: encParamsBufToHex(encryptedSeed), + public_key: encodeEd25519Point(finalEd25519Key.point).toString("hex"), }; const encDataBase64 = Buffer.from(JSON.stringify(encData), "utf-8").toString("base64"); @@ -115,24 +121,33 @@ export const generateEd25519KeyData = async (ed25519Seed: BN): Promise => { - const key = secp256k1Curve.keyFromPrivate(scalar.toString("hex", 64)); const randomNonce = new BN(generatePrivateKey(secp256k1Curve, Buffer)); const oAuthKey = scalar.sub(randomNonce).umod(secp256k1Curve.curve.n); - const oAuthPubKey = secp256k1Curve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); + const oAuthKeyPair = secp256k1Curve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")); + const oAuthPubKey = oAuthKeyPair.getPublic(); + + const finalUserKeyPair = secp256k1Curve.keyFromPrivate(scalar.toString("hex", 64)); + return { - oAuthKeyScalar: key.getPrivate(), + oAuthKeyScalar: oAuthKeyPair.getPrivate(), oAuthPubX: oAuthPubKey.getX(), oAuthPubY: oAuthPubKey.getY(), + SigningPubX: oAuthPubKey.getX(), + SigningPubY: oAuthPubKey.getY(), metadataNonce: randomNonce, encryptedSeed: "", - encryptionScalar: new BN(0), + metadataSigningKey: oAuthKeyPair.getPrivate(), + finalUserPubKeyPoint: finalUserKeyPair.getPublic(), }; }; @@ -172,7 +187,7 @@ export const generateShares = async ( privKey: BN ) => { const keyData = keyType === "ed25519" ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); - const { metadataNonce, oAuthKeyScalar: oAuthKey } = keyData; + const { metadataNonce, oAuthKeyScalar: oAuthKey, encryptedSeed, metadataSigningKey } = keyData; const threshold = ~~(nodePubkeys.length / 2) + 1; const degree = threshold - 1; const nodeIndexesBn: BN[] = []; @@ -183,7 +198,7 @@ export const generateShares = async ( const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); const shares = poly.generateShares(nodeIndexesBn); - const nonceParams = generateNonceMetadataParams(ecCurve, serverTimeOffset, "getOrSetNonce", oAuthKey, keyType, metadataNonce); + const nonceParams = generateNonceMetadataParams(serverTimeOffset, "getOrSetNonce", metadataSigningKey, keyType, metadataNonce, encryptedSeed); const nonceData = Buffer.from(stringify(nonceParams.set_data), "utf8").toString("base64"); const sharesData: ImportedShare[] = []; const encPromises: Promise[] = []; @@ -204,8 +219,11 @@ export const generateShares = async ( const encParamsMetadata = encParamsBufToHex(encParams); const shareData: ImportedShare = { encrypted_seed: keyData.encryptedSeed, - pub_key_x: oAuthPubKey.getX().toString("hex", 64), - pub_key_y: oAuthPubKey.getY().toString("hex", 64), + final_user_point: keyData.finalUserPubKeyPoint, + oauth_pub_key_x: oAuthPubKey.getX().toString("hex", 64), + oauth_pub_key_y: oAuthPubKey.getY().toString("hex", 64), + signing_pub_key_x: keyData.SigningPubX.toString("hex"), + signing_pub_key_y: keyData.SigningPubY.toString("hex"), encrypted_share: encParamsMetadata.ciphertext, encrypted_share_metadata: encParamsMetadata, node_index: Number.parseInt(shareJson.shareIndex, 16), diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index bc221c4..a9f24b0 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -5,9 +5,9 @@ import { ec } from "elliptic"; import stringify from "json-stable-stringify"; import log from "loglevel"; -import { EciesHex, GetOrSetNonceResult, KeyType, MetadataParams, NonceMetadataParams, SetNonceData } from "../interfaces"; -import { encParamsHexToBuf } from "./common"; -import { keccak256 } from "./keyUtils"; +import { EciesHex, EncryptedSeed, GetOrSetNonceResult, KeyType, MetadataParams, NonceMetadataParams, SetNonceData } from "../interfaces"; +import { encParamsHexToBuf, secp256k1Curve } from "./common"; +import { getSecpKeyFromEd25519, keccak256 } from "./keyUtils"; export function convertMetadataToNonce(params: { message?: string }) { if (!params || !params.message) { @@ -95,14 +95,15 @@ export async function getNonce( } export function generateNonceMetadataParams( - ecCurve: ec, serverTimeOffset: number, operation: string, privateKey: BN, keyType: KeyType, - nonce?: BN + nonce?: BN, + seed?: string ): NonceMetadataParams { - const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); + // metadata only uses secp for sig validation + const key = secp256k1Curve.keyFromPrivate(privateKey.toString("hex", 64)); const setData: Partial = { operation, timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), @@ -111,6 +112,11 @@ export function generateNonceMetadataParams( if (nonce) { setData.data = nonce.toString("hex", 64); } + + if (seed) { + setData.seed = seed; + } + const sig = key.sign(keccak256(Buffer.from(stringify(setData), "utf8")).slice(2)); return { pub_key_X: key.getPublic().getX().toString("hex", 64), @@ -120,3 +126,22 @@ export function generateNonceMetadataParams( signature: Buffer.from(sig.r.toString(16, 64) + sig.s.toString(16, 64) + new BN("").toString(16, 2), "hex").toString("base64"), }; } + +export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { + const decryptionKey = getSecpKeyFromEd25519(finalUserKey); + const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); + const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; + + const bufferMetadata = { + ephemPublicKey: Buffer.from(seedJson.metadata.ephemPublicKey, "hex"), + iv: Buffer.from(seedJson.metadata.iv, "hex"), + mac: Buffer.from(seedJson.metadata.mac, "hex"), + mode: "AES256", + }; + const decText = await decrypt(decryptionKey.scalar.toArrayLike(Buffer), { + ...bufferMetadata, + ciphertext: Buffer.from(seedJson.enc_text, "hex"), + }); + + return decText; +}; diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 5dc29c3..817a654 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -36,9 +36,18 @@ import { normalizeLegacyKeysResult, thresholdSame, } from "./common"; -import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generatePrivateKey, generateShares, keccak256 } from "./keyUtils"; +import { + derivePubKey, + encodeEd25519Point, + generateAddressFromPrivKey, + generateAddressFromPubKey, + generatePrivateKey, + generateShares, + getEd25519ExtendedPublicKey, + keccak256, +} from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; -import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils"; +import { decryptNodeData, decryptSeedData, getMetadata, getOrSetNonce } from "./metadataUtils"; export const GetPubKeyOrKeyAssign = async (params: { endpoints: string[]; @@ -348,8 +357,10 @@ export async function retrieveOrImportShare(params: { idtoken: idToken, nodesignatures: nodeSigs, verifieridentifier: verifier, - pub_key_x: importedShare.pub_key_x, - pub_key_y: importedShare.pub_key_y, + pub_key_x: importedShare.oauth_pub_key_x, + pub_key_y: importedShare.oauth_pub_key_y, + signing_pub_key_x: importedShare.signing_pub_key_x, + signing_pub_key_y: importedShare.signing_pub_key_y, encrypted_share: importedShare.encrypted_share, encrypted_share_metadata: importedShare.encrypted_share_metadata, node_index: importedShare.node_index, @@ -366,7 +377,6 @@ export async function retrieveOrImportShare(params: { encrypted: "yes", use_temp: true, item: items, - encrypted_seed: items[0]?.encrypted_seed || "", key_type: keyType, one_key_flow: true, }), @@ -738,6 +748,18 @@ export async function retrieveOrImportShare(params: { } else if (typeOfUser === "v2") { isUpgraded = metadataNonce.eq(new BN("0")); } + + if (keyType === "ed25519") { + if (!nonceResult.seed) { + throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); + } + const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(finalPrivKey, "hex")); + const extendedEd25519Key = getEd25519ExtendedPublicKey(new BN(decryptedSeed)); + const encodedPubKey = encodeEd25519Point(extendedEd25519Key.point); + const totalLength = decryptedSeed.length + encodedPubKey.length; + finalPrivKey = Buffer.concat([decryptedSeed, encodedPubKey], totalLength).toString("hex"); + finalPubKey = extendedEd25519Key.point; + } // return reconstructed private key and ethereum address return { finalKeyData: { diff --git a/src/interfaces.ts b/src/interfaces.ts index bac2003..ad21ec9 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,6 +1,7 @@ import type { INodePub, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import BN from "bn.js"; +import { curve } from "elliptic"; export interface KeyIndex { index: string; @@ -9,15 +10,23 @@ export interface KeyIndex { } export type UserType = "v1" | "v2"; -export type v2NonceResultType = { typeOfUser: "v2"; nonce?: string; pubNonce: { x: string; y: string }; ipfs?: string; upgraded: boolean }; +export type v2NonceResultType = { + typeOfUser: "v2"; + nonce?: string; + seed?: string; + pubNonce: { x: string; y: string }; + ipfs?: string; + upgraded: boolean; +}; -export type v1NonceResultType = { typeOfUser: "v1"; nonce?: string }; +export type v1NonceResultType = { typeOfUser: "v1"; nonce?: string; seed?: string }; export type GetOrSetNonceResult = v2NonceResultType | v1NonceResultType; export type KeyType = "secp256k1" | "ed25519"; export interface SetNonceData { operation: string; data: string; + seed?: string; timestamp: string; } @@ -28,6 +37,7 @@ export interface NonceMetadataParams { set_data: Partial; signature: string; key_type?: KeyType; + seed?: string; } export interface TorusCtorOptions { @@ -161,8 +171,11 @@ export interface ShareRequestResult { } export interface ImportedShare { - pub_key_x: string; - pub_key_y: string; + oauth_pub_key_x: string; + oauth_pub_key_y: string; + final_user_point: curve.base.BasePoint; + signing_pub_key_x: string; + signing_pub_key_y: string; encrypted_share: string; encrypted_share_metadata: EciesHex; encrypted_seed?: string; @@ -247,7 +260,16 @@ export interface PrivateKeyData { oAuthKeyScalar: BN; oAuthPubX: BN; oAuthPubY: BN; + SigningPubX: BN; + SigningPubY: BN; metadataNonce: BN; encryptedSeed?: string; - encryptionScalar?: BN; + finalUserPubKeyPoint: curve.base.BasePoint; + metadataSigningKey?: BN; +} + +export interface EncryptedSeed { + enc_text: string; + public_key?: string; + metadata: EciesHex; } diff --git a/src/loglevel.ts b/src/loglevel.ts index 1d33267..d8d3e53 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.disableAll(); +log.enableAll(); export default log; diff --git a/src/torus.ts b/src/torus.ts index addd7a6..fb67577 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -16,6 +16,7 @@ import { config } from "./config"; import { calculateMedian, derivePubKey, + encodeEd25519Point, generateAddressFromPrivKey, generateAddressFromPubKey, generateShares, @@ -216,8 +217,28 @@ class Torus { if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, newPrivateKey); + const privKeyBuffer = new Uint8Array(Buffer.from(newPrivateKey, "hex")); + + if (this.keyType === "secp256k1" && privKeyBuffer.length !== 32) { + throw new Error("Invalid private key length for give secp256k1 key"); + } + if (this.keyType === "ed25519" && privKeyBuffer.length !== 64) { + throw new Error("Invalid private key length for give secp256k1 key"); + } + + const finalPrivKey = this.keyType === "secp256k1" ? privKeyBuffer : privKeyBuffer.slice(0, 32); + const privKeyBn = new BN(finalPrivKey, 16); + const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBn); + if (this.keyType === "ed25519") { + const ed25519PubKey = privKeyBuffer.slice(32); + const encodedPubKey = encodeEd25519Point(sharesData[0].final_user_point); + const importedPubKey = Buffer.from(ed25519PubKey).toString("hex"); + const derivedPubKey = encodedPubKey.toString("hex"); + if (importedPubKey !== derivedPubKey) { + throw new Error("invalid shares data for ed25519 key, public key is not matching after generating shares"); + } + } return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -631,6 +652,7 @@ class Torus { keyType: this.keyType, extendedVerifierId, }); + const { errorResult, keyResult, nodeIndexes = [], serverTimeOffset } = keyAssignResult; const finalServerTimeOffset = this.serverTimeOffset || serverTimeOffset; const { nonceResult } = keyAssignResult; diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 38c7d57..b8cf63b 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -1,15 +1,14 @@ +/* eslint-disable no-console */ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; -import { ec as EC } from "elliptic"; import faker from "faker"; -import { generatePrivateKey, getEd25519ExtendedPublicKey, keccak256 } from "../src"; +import { ed25519Curve, encodeEd25519Point, keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; -const ec = new EC("ed25519"); const TORUS_TEST_EMAIL = "ed25519@tor.us"; const TORUS_IMPORT_EMAIL = "importeduser5@tor.us"; @@ -36,10 +35,13 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); it("should be able to import a key for a new user", async function () { - const email = faker.internet.email(); + const email = "Willa_Funk@gmail.com"; + console.log("email", email); const token = generateIdToken(email, "ES256"); - const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); - const privHex = privKeyBuffer.toString("hex", 64); + // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); + // key exported from phantom wallet + const privHex = + "0942c4f0dfe419364b716925e1138977b66844c96873aeaa02efb7bbc7d82628247e13570f52dba8b44eb074553829f40f3da034570213f5367ab9e615a0f04c"; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( @@ -51,31 +53,35 @@ describe.only("torus utils ed25519 sapphire devnet", function () { token, privHex ); - expect(result.finalKeyData.privKey).to.be.equal(privHex); + console.log("result", result); + // expect(result.finalKeyData.privKey).to.be.equal(privHex); }); it("should be able to login", async function () { - const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); + const testEmail = "alssaaaeqsaapkasaaal"; + const token = generateIdToken(testEmail, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( torusNodeEndpoints, nodeDetails.torusIndexes, TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, + { verifier_id: testEmail }, token, nodeDetails.torusNodePub ); - expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); + console.log("result", result); + // expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); }); - it.only("should fetch public address", async function () { - const randomKey = ec.genKeyPair(); - getEd25519ExtendedPublicKey(randomKey.getPrivate()); - // const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "aslkasakl" }; - // const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - // const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - // const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - // console.log("result", result); + it("should fetch public address", async function () { + // const randomKey = ec.genKeyPair(); + // getEd25519ExtendedPublicKey(randomKey.getPrivate()); + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "aslkasaasasaakl" }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + + console.log("result", result); // expect(result.finalKeyData.X).to.equal("3af3d1e4e10d65ddb96210d5865ddab5b7c5fbe2bad157a6497615cfa8e9bcf5"); // expect(result).eql({ // oAuthKeyData: { @@ -114,16 +120,20 @@ describe.only("torus utils ed25519 sapphire devnet", function () { expect(result.metadata.upgraded).to.equal(false); }); - it("should keep public address same", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: faker.internet.email() }; + it.only("should keep public address same", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk@gmail.com" }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result1.finalKeyData).eql(result2.finalKeyData); - expect(result1.oAuthKeyData).eql(result2.oAuthKeyData); - expect(result1.metadata).eql(result2.metadata); + console.log("result1", result1); + const keyPair = ed25519Curve.keyFromPublic({ x: result1.finalKeyData.X, y: result1.finalKeyData.Y }); + const encodedPubKey = encodeEd25519Point(keyPair.getPublic()); + console.log("compressed pub key", encodedPubKey.toString("hex")); + // const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + // expect(result1.finalKeyData).eql(result2.finalKeyData); + // expect(result1.oAuthKeyData).eql(result2.oAuthKeyData); + // expect(result1.metadata).eql(result2.metadata); }); it("should fetch user type and public address", async function () { From 6950486a0c499e3aedbc43079b24699ea6b3fe49 Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 18 Mar 2024 15:32:31 +0530 Subject: [PATCH 19/56] fix tests for ed25519 keys --- package-lock.json | 14 ++ package.json | 1 + src/helpers/common.ts | 11 +- src/helpers/keyUtils.ts | 35 ++- src/helpers/nodeUtils.ts | 58 ++--- src/interfaces.ts | 4 +- src/torus.ts | 42 ++-- test/aqua.test.ts | 38 ++-- test/celeste.test.ts | 44 ++-- test/cyan.test.ts | 44 ++-- test/mainnet.test.ts | 40 ++-- test/onekey.test.ts | 38 ++-- test/sapphire_devnet.test.ts | 86 ++++---- test/sapphire_devnet_ed25519.test.ts | 306 ++++++++++++--------------- test/sapphire_mainnet.test.ts | 52 ++--- test/testnet.test.ts | 44 ++-- 16 files changed, 433 insertions(+), 424 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28fe2fb..e0130fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@toruslabs/eccrypto": "^4.0.0", "@toruslabs/http-helpers": "^6.0.0", "bn.js": "^5.2.1", + "bs58": "^5.0.0", "elliptic": "^6.5.4", "ethereum-cryptography": "^2.1.2", "json-stable-stringify": "^1.1.0", @@ -4474,6 +4475,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4818,6 +4824,14 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dependencies": { + "base-x": "^4.0.0" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", diff --git a/package.json b/package.json index 749b34e..ded69c0 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@toruslabs/eccrypto": "^4.0.0", "@toruslabs/http-helpers": "^6.0.0", "bn.js": "^5.2.1", + "bs58": "^5.0.0", "elliptic": "^6.5.4", "ethereum-cryptography": "^2.1.2", "json-stable-stringify": "^1.1.0", diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 1dbe0d2..d39263a 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -3,11 +3,20 @@ import { BN } from "bn.js"; import { ec as EC } from "elliptic"; import JsonStringify from "json-stable-stringify"; -import { EciesHex, LegacyVerifierLookupResponse, VerifierLookupResponse } from "../interfaces"; +import { EciesHex, KeyType, LegacyVerifierLookupResponse, VerifierLookupResponse } from "../interfaces"; import { keccak256 } from "."; export const ed25519Curve = new EC("ed25519"); export const secp256k1Curve = new EC("secp256k1"); + +export const getKeyCurve = (keyType: KeyType) => { + if (keyType === "ed25519") { + return ed25519Curve; + } else if (keyType === "secp256k1") { + return secp256k1Curve; + } + throw new Error(`Invalid keyType: ${keyType}`); +}; // this function normalizes the result from nodes before passing the result to threshold check function // For ex: some fields returns by nodes might be different from each other // like created_at field might vary and nonce_data might not be returned by all nodes because diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 4b64973..ca6ba68 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,6 +1,7 @@ import { INodePub } from "@toruslabs/constants"; import { Ecies, encrypt } from "@toruslabs/eccrypto"; import BN from "bn.js"; +import base58 from "bs58"; import { curve, ec as EC } from "elliptic"; import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import { sha512 } from "ethereum-cryptography/sha512"; @@ -8,7 +9,7 @@ import stringify from "json-stable-stringify"; import log from "loglevel"; import { EncryptedSeed, ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; -import { ed25519Curve, encParamsBufToHex, secp256k1Curve } from "./common"; +import { ed25519Curve, encParamsBufToHex, getKeyCurve, secp256k1Curve } from "./common"; import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; import { generateNonceMetadataParams } from "./metadataUtils"; @@ -151,18 +152,34 @@ export const generateSecp256k1KeyData = async (scalar: BN): Promise 0) { @@ -221,6 +219,8 @@ export async function retrieveOrImportShare(params: { finalImportedShares = [...finalImportedShares, ...generatedShares]; } + const tokenCommitment = keccak256(Buffer.from(idToken, "utf8")); + // make commitment requests to endpoints for (let i = 0; i < endpoints.length; i += 1) { /* @@ -269,7 +269,7 @@ export async function retrieveOrImportShare(params: { // for fetching existing imported keys we can rely on threshold nodes commitment if (overrideExistingKey && completedRequests.length === endpoints.length) { const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { - if (resp && resp.result?.nodeindex === "1") { + if (resp) { return true; } return false; @@ -278,9 +278,6 @@ export async function retrieveOrImportShare(params: { return Promise.resolve(resultArr); } } else if (!overrideExistingKey && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { - // for import shares, proxy node response is required. - // proxy node returns metadata unlike dkg keys where node 1 is checked for metadata. - // if user's account already const nodeSigs: CommitmentRequestResult[] = []; for (let i = 0; i < completedRequests.length; i += 1) { const x = completedRequests[i]; @@ -294,6 +291,9 @@ export async function retrieveOrImportShare(params: { ~~(endpoints.length / 2) + 1 ); const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); + // for import shares, proxy node response is required. + // proxy node returns metadata. + // if user's account already const requiredNodeIndex = indexes[proxyEndpointNum].toString(10); // if not a existing key we need to wait for nodes to agree on commitment @@ -312,7 +312,7 @@ export async function retrieveOrImportShare(params: { } else if (completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { // this case is for dkg keys const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { - if (resp && resp.result?.nodeindex === "1") { + if (resp) { return true; } return false; @@ -730,46 +730,48 @@ export async function retrieveOrImportShare(params: { throw new Error("Invalid public key, this might be a bug, please report this to web3auth team"); } - const oAuthKeyAddress = generateAddressFromPrivKey(ecCurve, oAuthKey); - - // deriving address from pub key coz pubkey is always available - // but finalPrivKey won't be available for v2 user upgraded to 2/n - const finalEvmAddress = generateAddressFromPubKey(ecCurve, finalPubKey.getX(), finalPubKey.getY()); - let finalPrivKey = ""; // it is empty for v2 user upgraded to 2/n - if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); - finalPrivKey = privateKeyWithNonce.toString("hex", 64); - } - let isUpgraded: boolean | null = false; + const oAuthKeyAddress = generateAddressFromPrivKey(keyType, oAuthKey); + // deriving address from pub key coz pubkey is always available + // but finalPrivKey won't be available for v2 user upgraded to 2/n + const finalWalletAddress = generateAddressFromPubKey(keyType, finalPubKey.getX(), finalPubKey.getY()); + let keyWithNonce = ""; if (typeOfUser === "v1") { isUpgraded = null; } else if (typeOfUser === "v2") { isUpgraded = metadataNonce.eq(new BN("0")); } - if (keyType === "ed25519") { - if (!nonceResult.seed) { + if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + keyWithNonce = privateKeyWithNonce.toString("hex", 64); + } + if (keyType === "secp256k1") { + finalPrivKey = keyWithNonce; + } else if (keyType === "ed25519") { + const finalPubKeyPair = ecCurve.keyFromPublic({ x: finalPubKey.getX().toString("hex"), y: finalPubKey.getY().toString("hex") }); + const encodedPubKey = encodeEd25519Point(finalPubKeyPair.getPublic()); + if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); + } else if (keyWithNonce && nonceResult.seed) { + const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); + const totalLength = decryptedSeed.length + encodedPubKey.length; + finalPrivKey = Buffer.concat([decryptedSeed, encodedPubKey], totalLength).toString("hex"); } - const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(finalPrivKey, "hex")); - const extendedEd25519Key = getEd25519ExtendedPublicKey(new BN(decryptedSeed)); - const encodedPubKey = encodeEd25519Point(extendedEd25519Key.point); - const totalLength = decryptedSeed.length + encodedPubKey.length; - finalPrivKey = Buffer.concat([decryptedSeed, encodedPubKey], totalLength).toString("hex"); - finalPubKey = extendedEd25519Key.point; + } else { + throw new Error(`Invalid keyType: ${keyType}`); } // return reconstructed private key and ethereum address return { finalKeyData: { - evmAddress: finalEvmAddress, + walletAddress: finalWalletAddress, X: finalPubKey.getX().toString(16, 64), // this is final pub x user before and after updating to 2/n Y: finalPubKey.getY().toString(16, 64), // this is final pub y user before and after updating to 2/n privKey: finalPrivKey, }, oAuthKeyData: { - evmAddress: oAuthKeyAddress, + walletAddress: oAuthKeyAddress, X: oAuthPubkeyX, Y: oAuthPubkeyY, privKey: oAuthKey.toString("hex", 64).padStart(64, "0"), diff --git a/src/interfaces.ts b/src/interfaces.ts index ad21ec9..0767444 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -194,12 +194,12 @@ export interface SessionToken { } export interface TorusPublicKey { finalKeyData: { - evmAddress: string; + walletAddress: string; // format depends on key type X: string; // this is final pub x user before and after updating to 2/n Y: string; // this is final pub y user before and after updating to 2/n }; oAuthKeyData: { - evmAddress: string; + walletAddress: string; // format depends on key type X: string; Y: string; }; diff --git a/src/torus.ts b/src/torus.ts index fb67577..1175a88 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -82,9 +82,11 @@ class Torus { legacyMetadataHost, keyType = "secp256k1", }: TorusCtorOptions) { - if (!clientId) throw Error("Please provide a valid clientId in constructor"); - if (!network) throw Error("Please provide a valid network in constructor"); - + if (!clientId) throw new Error("Please provide a valid clientId in constructor"); + if (!network) throw new Error("Please provide a valid network in constructor"); + if (keyType === "ed25519" && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { + throw new Error(`keyType: ${keyType} is not supported by ${network} network`); + } this.keyType = keyType; this.ec = new EC(this.keyType); this.serverTimeOffset = serverTimeOffset || 0; // ms @@ -218,7 +220,7 @@ class Torus { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const privKeyBuffer = new Uint8Array(Buffer.from(newPrivateKey, "hex")); + const privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); if (this.keyType === "secp256k1" && privKeyBuffer.length !== 32) { throw new Error("Invalid private key length for give secp256k1 key"); @@ -289,6 +291,9 @@ class Torus { keyType: KeyType, extraParams: Record = {} ): Promise { + if (this.keyType !== "secp256k1") { + throw new Error(`Given keyType: ${this.keyType} is not supported on network: ${this.network}`); + } const promiseArr = []; await get( this.allowHost, @@ -536,7 +541,7 @@ class Torus { finalPubKey = this.ec.keyFromPrivate(privateKeyWithNonce.toString("hex", 64), "hex").getPublic(); } - const oAuthKeyAddress = generateAddressFromPrivKey(this.ec, oAuthKey); + const oAuthKeyAddress = generateAddressFromPrivKey(this.keyType, oAuthKey); let finalPrivKey = ""; // it is empty for v2 user upgraded to 2/n if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { @@ -553,22 +558,22 @@ class Torus { // deriving address from pub key coz pubkey is always available // but finalPrivKey won't be available for v2 user upgraded to 2/n - let finalEvmAddress = ""; + let walletAddress = ""; if (finalPubKey) { - finalEvmAddress = generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()); + walletAddress = generateAddressFromPubKey(this.keyType, finalPubKey.getX(), finalPubKey.getY()); } else { throw new Error("Invalid public key, this might be a bug, please report this to web3auth team"); } return { finalKeyData: { - evmAddress: finalEvmAddress, + walletAddress, X: finalPubKey ? finalPubKey.getX().toString(16, 64) : "", // this is final pub x user before and after updating to 2/n Y: finalPubKey ? finalPubKey.getY().toString(16, 64) : "", // this is final pub y user before and after updating to 2/n privKey: finalPrivKey, }, oAuthKeyData: { - evmAddress: oAuthKeyAddress, + walletAddress: oAuthKeyAddress, X: oAuthKeyX, Y: oAuthKeyY, privKey: oAuthKey.toString("hex", 64).padStart(64, "0"), @@ -597,6 +602,9 @@ class Torus { { verifier, verifierId }: { verifier: string; verifierId: string }, enableOneKey: boolean ): Promise { + if (this.keyType !== "secp256k1") { + throw new Error(`Given keyType: ${this.keyType} is not supported on network: ${this.network}`); + } let finalKeyResult: LegacyVerifierLookupResponse | undefined; let isNewKey = false; @@ -707,22 +715,22 @@ class Torus { } const oAuthX = oAuthPubKey.getX().toString(16, 64); const oAuthY = oAuthPubKey.getY().toString(16, 64); - const oAuthAddress = generateAddressFromPubKey(this.ec, oAuthPubKey.getX(), oAuthPubKey.getY()); + const oAuthAddress = generateAddressFromPubKey(this.keyType, oAuthPubKey.getX(), oAuthPubKey.getY()); if (!finalPubKey) { throw new Error("Unable to derive finalPubKey"); } const finalX = finalPubKey ? finalPubKey.getX().toString(16, 64) : ""; const finalY = finalPubKey ? finalPubKey.getY().toString(16, 64) : ""; - const finalAddress = finalPubKey ? generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()) : ""; + const finalAddress = finalPubKey ? generateAddressFromPubKey(this.keyType, finalPubKey.getX(), finalPubKey.getY()) : ""; return { oAuthKeyData: { - evmAddress: oAuthAddress, + walletAddress: oAuthAddress, X: oAuthX, Y: oAuthY, }, finalKeyData: { - evmAddress: finalAddress, + walletAddress: finalAddress, X: finalX, Y: finalY, }, @@ -793,22 +801,22 @@ class Torus { } const oAuthX = oAuthPubKey.getX().toString(16, 64); const oAuthY = oAuthPubKey.getY().toString(16, 64); - const oAuthAddress = generateAddressFromPubKey(this.ec, oAuthPubKey.getX(), oAuthPubKey.getY()); + const oAuthAddress = generateAddressFromPubKey(this.keyType, oAuthPubKey.getX(), oAuthPubKey.getY()); if (typeOfUser === "v2" && !finalPubKey) { throw new Error("Unable to derive finalPubKey"); } const finalX = finalPubKey ? finalPubKey.getX().toString(16, 64) : ""; const finalY = finalPubKey ? finalPubKey.getY().toString(16, 64) : ""; - const finalAddress = finalPubKey ? generateAddressFromPubKey(this.ec, finalPubKey.getX(), finalPubKey.getY()) : ""; + const finalAddress = finalPubKey ? generateAddressFromPubKey(this.keyType, finalPubKey.getX(), finalPubKey.getY()) : ""; return { oAuthKeyData: { - evmAddress: oAuthAddress, + walletAddress: oAuthAddress, X: oAuthX, Y: oAuthY, }, finalKeyData: { - evmAddress: finalAddress, + walletAddress: finalAddress, X: finalX, Y: finalY, }, diff --git a/test/aqua.test.ts b/test/aqua.test.ts index 09c9f7c..2397806 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -28,18 +28,18 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xDfA967285AC699A70DA340F60d00DB19A272639d"); + expect(result.finalKeyData.walletAddress).to.equal("0xDfA967285AC699A70DA340F60d00DB19A272639d"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, finalKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, @@ -64,12 +64,12 @@ describe("torus utils aqua", function () { expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", + walletAddress: "0xDfA967285AC699A70DA340F60d00DB19A272639d", X: "4fc8db5d3fe164a3ab70fd6348721f2be848df2cc02fd2db316a154855a7aa7d", Y: "f76933cbf5fe2916681075bb6cb4cde7d5f6b6ce290071b1b7106747d906457c", }, finalKeyData: { - evmAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438", + walletAddress: "0x79F06350eF34Aeed4BE68e26954D405D573f1438", X: "99df45abc8e6ee03d2f94df33be79e939eadfbed20c6b88492782fdc3ef1dfd3", Y: "12bf3e54599a177fdb88f8b22419df7ddf1622e1d2344301edbe090890a72b16", }, @@ -98,12 +98,12 @@ describe("torus utils aqua", function () { expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828", + walletAddress: "0x4ea5260fF85678A2a326D08DF9C44d1f559a5828", X: "0e6febe33a9d4eeb680cc6b63ff6237ad1971f27adcd7f104a3b1de18eda9337", Y: "a5a915561f3543688e71281a850b9ee10b9690f305d9e79028dfc8359192b82d", }, finalKeyData: { - evmAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD", + walletAddress: "0xBc32f315515AdE7010cabC5Fd68c966657A570BD", X: "4897f120584ee18a72b9a6bb92c3ef6e45fc5fdff70beae7dc9325bd01332022", Y: "2066dbef2fcdded4573e3c04d1c04edd5d44662168e636ed9d0b0cbe2e67c968", }, @@ -131,12 +131,12 @@ describe("torus utils aqua", function () { expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", + walletAddress: "0x4ce0D09C3989eb3cC9372cC27fa022D721D737dD", X: "e76d2f7fa2c0df324b4ab74629c3af47aa4609c35f1d2b6b90b77a47ab9a1281", Y: "b33b35148d72d357070f66372e07fec436001bdb15c098276b120b9ed64c1e5f", }, finalKeyData: { - evmAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", + walletAddress: "0x5469C5aCB0F30929226AfF4622918DA8E1424a8D", X: "c20fac685bb67169e92f1d5d8894d4eea18753c0ef3b7b1b2224233b2dfa3539", Y: "c4f080b5c8d5c55c8eaba4bec70f668f36db4126f358b491d631fefea7c19d21", }, @@ -159,10 +159,10 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -185,13 +185,13 @@ describe("torus utils aqua", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", + walletAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", // TODO: fix this privKey }, oAuthKeyData: { - evmAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", + walletAddress: "0x9EBE51e49d8e201b40cAA4405f5E0B86d9D27195", X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", @@ -222,17 +222,17 @@ describe("torus utils aqua", function () { expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D"); expect(result).eql({ finalKeyData: { - evmAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", + walletAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", }, oAuthKeyData: { - evmAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", + walletAddress: "0x5b58d8a16fDA79172cd42Dc3068d5CEf26a5C81D", X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 7b326b6..83019f8 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -28,18 +28,18 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); + expect(result.finalKeyData.walletAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", + walletAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", }, finalKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", + walletAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", }, @@ -58,19 +58,19 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); + expect(result1.finalKeyData.walletAddress).to.equal("0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242"); expect(result1.metadata.typeOfUser).to.equal("v1"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", + walletAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", }, finalKeyData: { - evmAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", + walletAddress: "0xeC80FB9aB308Be1789Bd3f9317962D5505A4A242", X: "d1a99fbec9326f04687daea4261b15b68cc45671554d43e94529d62857bf236c", Y: "085bc72609f474b7b80081ecdc92d0dca241327195c7655c7a35b601c1f93e8e", }, @@ -90,18 +90,18 @@ describe("torus utils celeste", function () { verifier: v2Verifier, verifierId: v2TestEmail, }); - expect(result2.finalKeyData.evmAddress).to.equal("0x69fB3A96016817F698a1279aE2d65F3916F3Db6F"); + expect(result2.finalKeyData.walletAddress).to.equal("0x69fB3A96016817F698a1279aE2d65F3916F3Db6F"); expect(result2.metadata.typeOfUser).to.equal("v1"); delete result2.metadata.serverTimeOffset; expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", + walletAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", X: "9180a724488c99d7639f886e1920598618c2e599481d71ffd9f602c8a856ff20", Y: "c5da5c13fedf3a22964ab39afb871bff607479e2a5cb2e621608771b4276b44b", }, finalKeyData: { - evmAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", + walletAddress: "0x69fB3A96016817F698a1279aE2d65F3916F3Db6F", X: "9180a724488c99d7639f886e1920598618c2e599481d71ffd9f602c8a856ff20", Y: "c5da5c13fedf3a22964ab39afb871bff607479e2a5cb2e621608771b4276b44b", }, @@ -122,16 +122,16 @@ describe("torus utils celeste", function () { }); delete result3.metadata.serverTimeOffset; - expect(result3.finalKeyData.evmAddress).to.equal("0x24aCac36F8A4bD93052207dA410dA71AF92258b7"); + expect(result3.finalKeyData.walletAddress).to.equal("0x24aCac36F8A4bD93052207dA410dA71AF92258b7"); expect(result3.metadata.typeOfUser).to.equal("v1"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", + walletAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", X: "95b242e13e394e252d9685bfc1937a2acfa25e0c5e1d37bfd5247879ae1468cc", Y: "687a6754180aec931ff65e55a058032107df519334b2f5c6fb1fc5157620a219", }, finalKeyData: { - evmAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", + walletAddress: "0x24aCac36F8A4bD93052207dA410dA71AF92258b7", X: "95b242e13e394e252d9685bfc1937a2acfa25e0c5e1d37bfd5247879ae1468cc", Y: "687a6754180aec931ff65e55a058032107df519334b2f5c6fb1fc5157620a219", }, @@ -151,10 +151,10 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, metadata, oAuthKeyData } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -171,13 +171,13 @@ describe("torus utils celeste", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", + walletAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", }, oAuthKeyData: { - evmAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", + walletAddress: "0x58420FB83971C4490D8c9B091f8bfC890D716617", X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", @@ -208,17 +208,17 @@ describe("torus utils celeste", function () { delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564"); expect(result).eql({ finalKeyData: { - evmAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", + walletAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", }, oAuthKeyData: { - evmAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", + walletAddress: "0x535Eb1AefFAc6f699A2a1A5846482d7b5b2BD564", X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", diff --git a/test/cyan.test.ts b/test/cyan.test.ts index 066b4d4..0ac9b64 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -28,19 +28,19 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xA3767911A84bE6907f26C572bc89426dDdDB2825"); + expect(result.finalKeyData.walletAddress).to.equal("0xA3767911A84bE6907f26C572bc89426dDdDB2825"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, finalKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, @@ -59,19 +59,19 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0x3507F0d192a44E436B8a6C32a37d57D022861b1a"); + expect(result1.finalKeyData.walletAddress).to.equal("0x3507F0d192a44E436B8a6C32a37d57D022861b1a"); expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); delete result1.metadata.serverTimeOffset; expect(result1).eql({ oAuthKeyData: { - evmAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", + walletAddress: "0xA3767911A84bE6907f26C572bc89426dDdDB2825", X: "2853f323437da98ce021d06854f4b292db433c0ad03b204ef223ac2583609a6a", Y: "f026b4788e23523e0c8fcbf0bdcf1c1a62c9cde8f56170309607a7a52a19f7c1", }, finalKeyData: { - evmAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a", + walletAddress: "0x3507F0d192a44E436B8a6C32a37d57D022861b1a", X: "8aaadab9530cb157d0b0dfb7b27d1a3aaca45274563c22c92c77ee2191779051", Y: "d57b89d9f62bb6609d8542c3057943805c8c72f6f27d39781b820f27d7210f12", }, @@ -98,16 +98,16 @@ describe("torus utils cyan", function () { delete result2.metadata.serverTimeOffset; - expect(result2.finalKeyData.evmAddress).to.equal("0x8EA83Ace86EB414747F2b23f03C38A34E0217814"); + expect(result2.finalKeyData.walletAddress).to.equal("0x8EA83Ace86EB414747F2b23f03C38A34E0217814"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e", + walletAddress: "0x29446f428293a4E6470AEaEDa6EAfA0F842EF54e", X: "8b6f2048aba8c7833e3b02c5b6522bb18c484ad0025156e428f17fb8d8c34021", Y: "cd9ba153ff89d665f655d1be4c6912f3ff93996e6fe580d89e78bf1476fef2aa", }, finalKeyData: { - evmAddress: "0x8EA83Ace86EB414747F2b23f03C38A34E0217814", + walletAddress: "0x8EA83Ace86EB414747F2b23f03C38A34E0217814", X: "cbe7b0f0332e5583c410fcacb6d4ff685bec053cfd943ac75f5e4aa3278a6fbb", Y: "b525c463f438c7a3c4b018c8c5d16c9ef33b9ac6f319140a22b48b17bdf532dd", }, @@ -130,16 +130,16 @@ describe("torus utils cyan", function () { }); delete result3.metadata.serverTimeOffset; - expect(result3.finalKeyData.evmAddress).to.equal("0xCC1f953f6972a9e3d685d260399D6B85E2117561"); + expect(result3.finalKeyData.walletAddress).to.equal("0xCC1f953f6972a9e3d685d260399D6B85E2117561"); expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b", + walletAddress: "0xe8a19482cbe5FaC896A5860Ca4156fb999DDc73b", X: "c491ba39155594896b27cf71a804ccf493289d918f40e6ba4d590f1c76139e9e", Y: "d4649ed9e46461e1af00399a4c65fabb1dc219b3f4af501a7d635c17f57ab553", }, finalKeyData: { - evmAddress: "0xCC1f953f6972a9e3d685d260399D6B85E2117561", + walletAddress: "0xCC1f953f6972a9e3d685d260399D6B85E2117561", X: "8d784434becaad9b23d9293d1f29c4429447315c4cac824cbf2eb21d3f7d79c8", Y: "fe46a0ef5efe33d16f6cfa678a597be930fbec5432cbb7f3580189c18bd7e157", }, @@ -162,10 +162,10 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -192,13 +192,13 @@ describe("torus utils cyan", function () { finalKeyData: { X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", - evmAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", + walletAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", }, oAuthKeyData: { X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", - evmAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", + walletAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, @@ -228,17 +228,17 @@ describe("torus utils cyan", function () { delete result.metadata.serverTimeOffset; - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04"); expect(result).eql({ finalKeyData: { - evmAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", + walletAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", }, oAuthKeyData: { - evmAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", + walletAddress: "0x34117FDFEFBf1ad2DFA6d4c43804E6C710a6fB04", X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index 4815524..0d1a523 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -28,17 +28,17 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A"); + expect(result.finalKeyData.walletAddress).to.equal("0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A"); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, finalKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, @@ -64,12 +64,12 @@ describe("torus utils mainnet", function () { expect(result1).eql({ oAuthKeyData: { - evmAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", + walletAddress: "0x0C44AFBb5395a9e8d28DF18e1326aa0F16b9572A", X: "3b5655d78978b6fd132562b5cb66b11bcd868bd2a9e16babe4a1ca50178e57d4", Y: "15338510798d6b55db28c121d86babcce19eb9f1882f05fae8ee9b52ed09e8f1", }, finalKeyData: { - evmAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", + walletAddress: "0xb2e1c3119f8D8E73de7eaF7A535FB39A3Ae98C5E", X: "072beda348a832aed06044a258cb6a8d428ec7c245c5da92db5da4f3ab433e55", Y: "54ace0d3df2504fa29f17d424a36a0f92703899fad0afee93d010f6d84b310e5", }, @@ -96,16 +96,16 @@ describe("torus utils mainnet", function () { delete result2.metadata.serverTimeOffset; - expect(result2.finalKeyData.evmAddress).to.equal("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526"); + expect(result2.finalKeyData.walletAddress).to.equal("0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2).eql({ oAuthKeyData: { - evmAddress: "0xA9c6829e4899b6D630130ebf59D046CA868D7f83", + walletAddress: "0xA9c6829e4899b6D630130ebf59D046CA868D7f83", X: "5566cd940ea540ba1a3ba2ff0f5fd3d9a3a74350ac3baf47b811592ae6ea1c30", Y: "07a302e87e8d9eb5d143f570c248657288c13c09ecbe1e3a8720449daf9315b0", }, finalKeyData: { - evmAddress: "0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", + walletAddress: "0xFf669A15bFFcf32D3C5B40bE9E5d409d60D43526", X: "bbfd26b1e61572c4e991a21b64f12b313cb6fce6b443be92d4d5fd8f311e8f33", Y: "df2c905356ec94faaa111a886be56ed6fa215b7facc1d1598486558355123c25", }, @@ -132,12 +132,12 @@ describe("torus utils mainnet", function () { expect(result3.metadata.typeOfUser).to.equal("v2"); expect(result3).eql({ oAuthKeyData: { - evmAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", + walletAddress: "0x61E52B6e488EC3dD6FDc0F5ed04a62Bb9c6BeF53", X: "c01282dd68d2341031a1cff06f70d821cad45140f425f1c25055a8aa64959df8", Y: "cb3937773bb819d60b780b6d4c2edcf27c0f7090ba1fc2ff42504a8138a8e2d7", }, finalKeyData: { - evmAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", + walletAddress: "0x40A4A04fDa1f29a3667152C8830112FBd6A77BDD", X: "6779af3031d9e9eec6b4133b0ae13e367c83a614f92d2008e10c7f3b8e6723bc", Y: "80edc4502abdfb220dd6e2fcfa2dbb058125dc95873e4bfa6877f9c26da7fdff", }, @@ -161,10 +161,10 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); // TorusUtils.enableLogging(false); @@ -189,13 +189,13 @@ describe("torus utils mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", + walletAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", }, oAuthKeyData: { - evmAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", + walletAddress: "0x90A926b698047b4A87265ba1E9D8b512E8489067", X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", @@ -222,8 +222,8 @@ describe("torus utils mainnet", function () { hashedIdToken.substring(2), torusNodePub ); - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -231,13 +231,13 @@ describe("torus utils mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", + walletAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", }, oAuthKeyData: { - evmAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", + walletAddress: "0x621a4d458cFd345dAE831D9E756F10cC40A50381", X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", diff --git a/test/onekey.test.ts b/test/onekey.test.ts index 3d91039..0587b23 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -31,19 +31,19 @@ describe("torus onekey", function () { const verifierDetails = { verifier, verifierId: "himanshu@tor.us" }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const publicAddress = (await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; - expect(publicAddress.finalKeyData.evmAddress).to.be.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); + expect(publicAddress.finalKeyData.walletAddress).to.be.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); expect(publicAddress.metadata.serverTimeOffset).lessThan(20); delete publicAddress.metadata.serverTimeOffset; expect(publicAddress).eql({ oAuthKeyData: { - evmAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", + walletAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", X: "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b", Y: "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a", }, finalKeyData: { - evmAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", + walletAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", X: "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425", Y: "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224", }, @@ -75,13 +75,13 @@ describe("torus onekey", function () { expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7", + walletAddress: "0x53010055542cCc0f2b6715a5c53838eC4aC96EF7", X: "3fa78a0bfb9ec48810bf1ee332360def2600c4aef528ff8b1e49a0d304722c91", Y: "46aaca39fc00c0f88f63a79989697c70eeeeec6489300c493dd07a5608ded0d4", privKey: "296045a5599afefda7afbdd1bf236358baff580a0fe2db62ae5c1bbe817fbae4", }, oAuthKeyData: { - evmAddress: "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4", + walletAddress: "0xEfd7eDAebD0D99D1B7C8424b54835457dD005Dc4", X: "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4", Y: "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a", privKey: "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", @@ -123,16 +123,16 @@ describe("torus onekey", function () { delete retrieveSharesResponse.metadata.serverTimeOffset; - expect(retrieveSharesResponse.finalKeyData.evmAddress).to.be.equal("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B"); + expect(retrieveSharesResponse.finalKeyData.walletAddress).to.be.equal("0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", + walletAddress: "0xE1155dB406dAD89DdeE9FB9EfC29C8EedC2A0C8B", X: "78658b2671f1bd6a488baf2afb8ce6f8d8b9a1a70842130b3c8756a9d51d9723", Y: "2e5840f47d645afa4bfe93c3715e65974051080d7a1e474eef8d68752924f4fb", privKey: "ad47959db4cb2e63e641bac285df1b944f54d1a1cecdaeea40042b60d53c35d2", }, oAuthKeyData: { - evmAddress: "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2", + walletAddress: "0x5a165d2Ed4976BD104caDE1b2948a93B72FA91D2", X: "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc", Y: "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27", privKey: "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a", @@ -162,10 +162,10 @@ describe("torus onekey", function () { const publicAddress = (await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails)) as TorusPublicKey; expect(publicAddress.metadata.typeOfUser).to.equal("v2"); expect(publicAddress.metadata.upgraded).to.equal(false); - expect(publicAddress.finalKeyData.evmAddress).to.not.equal(""); - expect(publicAddress.finalKeyData.evmAddress).to.not.equal(null); - expect(publicAddress.oAuthKeyData.evmAddress).to.not.equal(""); - expect(publicAddress.oAuthKeyData.evmAddress).to.not.equal(null); + expect(publicAddress.finalKeyData.walletAddress).to.not.equal(""); + expect(publicAddress.finalKeyData.walletAddress).to.not.equal(null); + expect(publicAddress.oAuthKeyData.walletAddress).to.not.equal(""); + expect(publicAddress.oAuthKeyData.walletAddress).to.not.equal(null); }); it("should be able to key assign via login", async function () { @@ -177,10 +177,10 @@ describe("torus onekey", function () { expect(!result.metadata.nonce.eq(new BN("0"))); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.upgraded).to.equal(false); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); }); it("should still login v2 account correctly", async function () { @@ -198,16 +198,16 @@ describe("torus onekey", function () { delete retrieveSharesResponse.metadata.serverTimeOffset; expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075"); - expect(retrieveSharesResponse.finalKeyData.evmAddress).to.be.equal("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2"); + expect(retrieveSharesResponse.finalKeyData.walletAddress).to.be.equal("0x2876820fd9536BD5dd874189A85d71eE8bDf64c2"); expect(retrieveSharesResponse).eql({ finalKeyData: { - evmAddress: "0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", + walletAddress: "0x2876820fd9536BD5dd874189A85d71eE8bDf64c2", X: "ad4c223520aac9bc3ec72399869601fd59f29363471131914e2ed2bc4ba46e54", Y: "802c6e40b22b49b5ef73fa49b194c2037267215fa01683aa86746907aab37ae1", privKey: "9ec5b0504e252e35218c7ce1e4660eac190a1505abfbec7102946f92ed750075", }, oAuthKeyData: { - evmAddress: "0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24", + walletAddress: "0x54de3Df0CA76AAe3e171FB410F0626Ab759f3c24", X: "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e", Y: "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc", privKey: "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a", diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index a15afa9..cda95e9 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -51,16 +51,16 @@ describe("torus utils sapphire devnet", function () { const { torusNodeSSSEndpoints: torusNodeEndpoints, torusNodePub } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const publicKeyData = await legacyTorus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); expect(publicKeyData.metadata.typeOfUser).to.equal("v1"); - expect(publicKeyData.finalKeyData.evmAddress).to.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); + expect(publicKeyData.finalKeyData.walletAddress).to.equal("0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1"); delete publicKeyData.metadata.serverTimeOffset; expect(publicKeyData).eql({ oAuthKeyData: { - evmAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", + walletAddress: "0xf1e76fcDD28b5AA06De01de508fF21589aB9017E", X: "b3f2b4d8b746353fe670e0c39ac9adb58056d4d7b718d06b623612d4ec49268b", Y: "ac9f79dff78add39cdba380dbbf517c20cf2c1e06b32842a90a84a31f6eb9a9a", }, finalKeyData: { - evmAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", + walletAddress: "0x930abEDDCa6F9807EaE77A3aCc5c78f20B168Fd1", X: "12f6b90d66bda29807cf9ff14b2e537c25080154fc4fafed446306e8356ff425", Y: "e7c92e164b83e1b53e41e5d87d478bb07d7b19d105143e426e1ef08f7b37f224", }, @@ -103,13 +103,13 @@ describe("torus utils sapphire devnet", function () { expect(retrieveSharesResponse).eql({ oAuthKeyData: { - evmAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", + walletAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", }, finalKeyData: { - evmAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", + walletAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", @@ -145,19 +145,19 @@ describe("torus utils sapphire devnet", function () { verifier: v2Verifier, verifierId: v2TestEmail, }); - expect(result.finalKeyData.evmAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); + expect(result.finalKeyData.walletAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x376597141d8d219553378313d18590F373B09795", + walletAddress: "0x376597141d8d219553378313d18590F373B09795", X: "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c", Y: "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2", }, finalKeyData: { - evmAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", + walletAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", X: "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e", Y: "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f", }, @@ -180,18 +180,18 @@ describe("torus utils sapphire devnet", function () { verifierId: v2nTestEmail, }); expect(data.metadata.typeOfUser).to.equal("v2"); - expect(data.finalKeyData.evmAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); + expect(data.finalKeyData.walletAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); expect(data.metadata.serverTimeOffset).lessThan(20); delete data.metadata.serverTimeOffset; expect(data).eql({ oAuthKeyData: { - evmAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", + walletAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", X: "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8", Y: "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5", }, finalKeyData: { - evmAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", + walletAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", X: "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7", Y: "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222", }, @@ -218,12 +218,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, @@ -244,11 +244,11 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.upgraded).to.equal(false); }); @@ -282,12 +282,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", }, finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", }, @@ -310,8 +310,8 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); }); it("should be able to login", async function () { @@ -331,13 +331,13 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", @@ -418,13 +418,13 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", + walletAddress: "0x462A8BF111A55C9354425F875F89B22678c0Bc44", X: "36e257717f746cdd52ba85f24f7c9040db8977d3b0354de70ed43689d24fa1b1", Y: "58ec9768c2fe871b3e2a83cdbcf37ba6a88ad19ec2f6e16a66231732713fd507", privKey: "230dad9f42039569e891e6b066ff5258b14e9764ef5176d74aeb594d1a744203", }, oAuthKeyData: { - evmAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", + walletAddress: "0x137B3607958562D03Eb3C6086392D1eFa01aA6aa", X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", @@ -494,7 +494,7 @@ describe("torus utils sapphire devnet", function () { ); expect(result.finalKeyData.privKey).to.be.equal(privHex); const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, verifierId: email }); - expect(result1.finalKeyData.evmAddress).to.be.equal(result.finalKeyData.evmAddress); + expect(result1.finalKeyData.walletAddress).to.be.equal(result.finalKeyData.walletAddress); }); it("should fetch pub address of tss verifier id", async function () { @@ -511,12 +511,12 @@ describe("torus utils sapphire devnet", function () { expect(result).eql({ oAuthKeyData: { - evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + walletAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", }, finalKeyData: { - evmAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", + walletAddress: "0xBd6Bc8aDC5f2A0526078Fd2016C4335f64eD3a30", X: "d45d4ad45ec643f9eccd9090c0a2c753b1c991e361388e769c0dfa90c210348c", Y: "fdc151b136aa7df94e97cc7d7007e2b45873c4b0656147ec70aad46e178bce1e", }, @@ -538,8 +538,8 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(false); @@ -562,7 +562,7 @@ describe("torus utils sapphire devnet", function () { nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); @@ -573,18 +573,18 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result.finalKeyData.walletAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", }, finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", }, @@ -619,19 +619,19 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); + expect(result.finalKeyData.walletAddress).to.equal("0xF79b5ffA48463eba839ee9C97D61c6063a96DA03"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", }, finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", }, @@ -666,13 +666,13 @@ describe("torus utils sapphire devnet", function () { expect(result.finalKeyData.privKey).to.be.equal("066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32"); expect(result).eql({ finalKeyData: { - evmAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", + walletAddress: "0xF79b5ffA48463eba839ee9C97D61c6063a96DA03", X: "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a", Y: "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e", privKey: "066270dfa345d3d0415c8223e045f366b238b50870de7e9658e3c6608a7e2d32", }, oAuthKeyData: { - evmAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", + walletAddress: "0x4135ad20D2E9ACF37D64E7A6bD8AC34170d51219", X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", @@ -717,9 +717,9 @@ describe("torus utils sapphire devnet", function () { expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.not.equal(null); expect(result.metadata.upgraded).to.equal(false); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index b8cf63b..8b3c6bd 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -1,18 +1,17 @@ -/* eslint-disable no-console */ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import { expect } from "chai"; import faker from "faker"; -import { ed25519Curve, encodeEd25519Point, keccak256 } from "../src"; +import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; -const TORUS_TEST_EMAIL = "ed25519@tor.us"; -const TORUS_IMPORT_EMAIL = "importeduser5@tor.us"; +const TORUS_TEST_EMAIL = "ed25519testuser@tor.us"; +const TORUS_TEST_EMAIL_HASHED = "ed25519testuserhash@tor.us"; -const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierid@example.com"; +const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierided25519@example.com"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -34,9 +33,38 @@ describe.only("torus utils ed25519 sapphire devnet", function () { TorusUtils.enableLogging(false); }); + it("should should fetch public address", async function () { + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk1@gmail.com" }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + delete result.metadata.serverTimeOffset; + expect(result).eql({ + oAuthKeyData: { + walletAddress: "A5fzWVa6YDLpsZ3d8Zg6qwB9dLgGMw1UbtRctZeXy89n", + X: "175d1cb8a3fe85a6079d1d1892ef0421cc5f692ebda617bc61f1c8891b1fbcb6", + Y: "397d5c7c0c1f543d83c0a8be2d2824ca4298ff5b34714c2982dae82beb97eb86", + }, + finalKeyData: { + walletAddress: "3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM", + X: "664cf57e06afdbd897a8be4ce6e572bd836e306611597d30be31e6250571e87a", + Y: "4cf0a015e6b97a36f513025734a03d0ff429385574b04eb4a8db520f57137e24", + }, + metadata: { + pubNonce: { + X: "439fe891f2f06a93f533aec3c2a1b0b247b7a6e52de4c8b943529e95224979b8", + Y: "51ed278447e030a8fca05362189f358c9d7eaff7818036b8c6c828e3eef40898", + }, + nonce: new BN("0", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + }); it("should be able to import a key for a new user", async function () { - const email = "Willa_Funk@gmail.com"; - console.log("email", email); + const email = "Willa_Funk1@gmail.com"; const token = generateIdToken(email, "ES256"); // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); // key exported from phantom wallet @@ -53,11 +81,29 @@ describe.only("torus utils ed25519 sapphire devnet", function () { token, privHex ); - console.log("result", result); - // expect(result.finalKeyData.privKey).to.be.equal(privHex); + expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + expect(result.finalKeyData.privKey).to.be.equal(privHex); + + const token1 = generateIdToken(email, "ES256"); + const result1 = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token1, + nodeDetails.torusNodePub + ); + expect(result1.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + expect(result.finalKeyData.privKey).to.be.equal(privHex); + + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: email, + }); + expect(result2.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); }); it("should be able to login", async function () { - const testEmail = "alssaaaeqsaapkasaaal"; + const testEmail = "edd2519TestUser@example.com"; const token = generateIdToken(testEmail, "ES256"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; @@ -69,110 +115,47 @@ describe.only("torus utils ed25519 sapphire devnet", function () { token, nodeDetails.torusNodePub ); - console.log("result", result); - // expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); - }); - - it("should fetch public address", async function () { - // const randomKey = ec.genKeyPair(); - // getEd25519ExtendedPublicKey(randomKey.getPrivate()); - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "aslkasaasasaakl" }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - - console.log("result", result); - // expect(result.finalKeyData.X).to.equal("3af3d1e4e10d65ddb96210d5865ddab5b7c5fbe2bad157a6497615cfa8e9bcf5"); - // expect(result).eql({ - // oAuthKeyData: { - // evmAddress: "0x89155E126aAC6ea94D479d8D7aB5e1BE4ed51eEF", - // X: "1dfd79a9c42f3ddce4b2601fe629ab1b70c0d8d133c33aead2007b865f63ad6c", - // Y: "06ab3522dd3710bd26bbe502c4cad0ef0c4ad47e87e13fb3143367ded3426a8f", - // }, - // finalKeyData: { - // evmAddress: "0x4b0426e4E8b605753336B88C2F5F8E79E9FdA7aA", - // X: "3af3d1e4e10d65ddb96210d5865ddab5b7c5fbe2bad157a6497615cfa8e9bcf5", - // Y: "47bb8524c3d6a895888e9fe4f903186a749de7766d0a14c421312d7c3ffc87ef", - // }, - // metadata: { - // pubNonce: { - // X: "1cecc501e8701081c4c61b3e7696aa8f2494e79013c18cdf9c4ad528d65cc4b3", - // Y: "459cb8092ac5e99b051cf135a639353d5a6bf4bc8785ec92bbaaee763d1c8963", - // }, - // nonce: new BN("0"), - // upgraded: false, - // typeOfUser: "v2", - // }, - // nodesData: result.nodesData, - // }); - }); - it("should fetch public address of imported user", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_IMPORT_EMAIL }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); - expect(result.metadata.typeOfUser).to.equal("v2"); - expect(result.metadata.upgraded).to.equal(false); - }); - it.only("should keep public address same", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk@gmail.com" }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - - const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - console.log("result1", result1); - const keyPair = ed25519Curve.keyFromPublic({ x: result1.finalKeyData.X, y: result1.finalKeyData.Y }); - const encodedPubKey = encodeEd25519Point(keyPair.getPublic()); - console.log("compressed pub key", encodedPubKey.toString("hex")); - // const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - // expect(result1.finalKeyData).eql(result2.finalKeyData); - // expect(result1.oAuthKeyData).eql(result2.oAuthKeyData); - // expect(result1.metadata).eql(result2.metadata); - }); - - it("should fetch user type and public address", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + delete result.metadata.serverTimeOffset; + delete result.sessionData; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x89155E126aAC6ea94D479d8D7aB5e1BE4ed51eEF", - X: "1dfd79a9c42f3ddce4b2601fe629ab1b70c0d8d133c33aead2007b865f63ad6c", - Y: "06ab3522dd3710bd26bbe502c4cad0ef0c4ad47e87e13fb3143367ded3426a8f", + walletAddress: "7yZNbrFdLgE1ck8BQvDfNpVsgU5BYXotEoXiasTwdWWr", + X: "7a5d7618aa6abff0a27fd273cd38ef2f81c19a67c488f65d2587b2d7a744dd70", + Y: "179de2aa479958f2a744b6a8810a38e27257679d09f183f9aa5b2ff81f40a367", + privKey: "0325b66f131f040fbd23f8feb9633f10440986c5413063f6dd3f23166503b5ea", }, finalKeyData: { - evmAddress: "0x4b0426e4E8b605753336B88C2F5F8E79E9FdA7aA", - X: "3af3d1e4e10d65ddb96210d5865ddab5b7c5fbe2bad157a6497615cfa8e9bcf5", - Y: "47bb8524c3d6a895888e9fe4f903186a749de7766d0a14c421312d7c3ffc87ef", + walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", + X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", + Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", + privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f78363b2efd7cf8c4bba1c56a830404ee1841c9039f6f7a6359906e150c593c082f0", }, metadata: { pubNonce: { - X: "1cecc501e8701081c4c61b3e7696aa8f2494e79013c18cdf9c4ad528d65cc4b3", - Y: "459cb8092ac5e99b051cf135a639353d5a6bf4bc8785ec92bbaaee763d1c8963", + X: "4533a0c1907b12187ab41bceaefee8d62b2709d66b67b51a6f39925bfb543933", + Y: "6862380e59f04a6bbdb3515ee386af44961b403cc61c7cb9725d2e60d250b82", }, - nonce: new BN("0", "hex"), + nonce: new BN("da32347189e4a992a9367cb8970d741fff3febccd9d92bb5ac247d97dc5c510", "hex"), typeOfUser: "v2", upgraded: false, }, nodesData: result.nodesData, }); + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: testEmail, + }); + expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); }); - it("should be able to key assign", async function () { const email = faker.internet.email(); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.finalKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.finalKeyData.walletAddress).to.not.equal(null); }); it("should be able to login even when node is down", async function () { @@ -188,7 +171,9 @@ describe.only("torus utils ed25519 sapphire devnet", function () { token, nodeDetails.torusNodePub ); - expect(result.finalKeyData.privKey).to.be.equal("08f54f7c3622a44dd4090397c001d4904d14646222775b29c5e4611f797d75e9"); + expect(result.finalKeyData.privKey).to.be.equal( + "ea39cc89d2d8b8403858d1c518fe82e2500cc83e472ba86d006323b57835a5197139cf3a4c9b145471ac5efcdcbeab630bfa7a387e672b4940f18d686effa30f" + ); }); it("should fetch pub address of tss verifier id", async function () { @@ -200,16 +185,17 @@ describe.only("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xdA7c5B1D01B511D8f0e921E047a17884B52a6F45", - X: "333a0a6b95514f9a92899970f9ae97bbd23f09fbc3b18f419d7dd23ae89c9579", - Y: "3ded16683d0c50c43749ff691e0e6f04a1597b5eccd85b602d8927d43ee2b6de", + walletAddress: "8YXTwFuGWc15bYSw7npC9nJpZzg3yoQpYPDe81DuKjGZ", + X: "0a89d65e3ba433f52aa86c6b1b832501dea6200a178ec1d1f2a17d556b551cba", + Y: "7ed3af68be167f590faec6a951c920730b760dd8f11af6a708dde3cc80421570", }, finalKeyData: { - evmAddress: "0xdA7c5B1D01B511D8f0e921E047a17884B52a6F45", - X: "333a0a6b95514f9a92899970f9ae97bbd23f09fbc3b18f419d7dd23ae89c9579", - Y: "3ded16683d0c50c43749ff691e0e6f04a1597b5eccd85b602d8927d43ee2b6de", + walletAddress: "8YXTwFuGWc15bYSw7npC9nJpZzg3yoQpYPDe81DuKjGZ", + X: "0a89d65e3ba433f52aa86c6b1b832501dea6200a178ec1d1f2a17d556b551cba", + Y: "7ed3af68be167f590faec6a951c920730b760dd8f11af6a708dde3cc80421570", }, metadata: { pubNonce: undefined, @@ -229,8 +215,8 @@ describe.only("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(false); @@ -253,76 +239,35 @@ describe.only("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); }); it("should fetch public address when verifierID hash enabled", async function () { - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; + const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL_HASHED }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x2b133a232194524A421EB5A7BE8F5Ad7df25a02A", - X: "299ad86ffe85fb33d8eee765908a031ae543af09f5226316d2367aa6d21df9af", - Y: "45d153c52d8b1eb12c2e2b5769284a4763ca7d61d8373f109d1997b6c647742b", + walletAddress: "FucMH9d3YMJD2qh2ums4Xqfw5Htc8PR6pYUzQnr2xgmK", + X: "161da0ab7a991abb8981968de76652880f09e479d1df4a15e5f4b537d244f1a5", + Y: "0effa9486c130b7e25e4181023c92ea69f1ee0ee835a0735bd7b446cfbc97ddd", }, finalKeyData: { - evmAddress: "0x86571392a487219B98395106234c6c0Be3732796", - X: "7b1ede24b623def02bc86e32702a4b1afd8dd31586e87f6d87887f3391c7bd6e", - Y: "347a62abfdbb488e5710eab49e1b8e88c3164d92a0095eaf8d087120a03baa59", + walletAddress: "74stJxXes7SP6T4uH2wRPiDQaeSc6dpEHdh1RtsFYsGQ", + X: "361660e9eb925988579d824ff6f4ea6cc8f35399b118f227ab233081aa72d50e", + Y: "3dbabd3baae7ad031e048d0b8f42efe1917d9291fd6a7d9476820dc04166245a", }, metadata: { pubNonce: { - X: "5e1b1653f2fa15da37d94a052be4e6ef37cd8bf9f5d4a10f1742e6a03134acac", - Y: "3a12ed5ac3ca5ca7ad056edc9ea6a16498b93c7a2669044d0154527a22c7dd5a", + X: "51b5cc6c5d917b97b28f0472bde7b04f67a1ce6745cd374d2586cc088a49b887", + Y: "39e4d6c342716e1bd9fca5553714d3e147a148c2b1eba5a77207db4a3246c205", }, - nonce: new BN("0"), - upgraded: false, - typeOfUser: "v2", - }, - nodesData: result.nodesData, - }); - }); - - // to do: update pub keys - it.skip("should lookup return hash when verifierID hash enabled", async function () { - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_VERIFIER }); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - for (const endpoint of torusNodeEndpoints) { - const pubKeyX = "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a"; - const pubKeyY = "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e"; - const response = await lookupVerifier(endpoint, pubKeyX, pubKeyY); - const verifierID = response.result.verifiers[HashEnabledVerifier][0]; - expect(verifierID).to.equal("086c23ab78578f2fce9a1da11c0071ec7c2225adb1bf499ffaee98675bee29b7"); - } - }); - - it("should fetch user type and public address when verifierID hash enabled", async function () { - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result).eql({ - oAuthKeyData: { - evmAddress: "0x2b133a232194524A421EB5A7BE8F5Ad7df25a02A", - X: "299ad86ffe85fb33d8eee765908a031ae543af09f5226316d2367aa6d21df9af", - Y: "45d153c52d8b1eb12c2e2b5769284a4763ca7d61d8373f109d1997b6c647742b", - }, - finalKeyData: { - evmAddress: "0x86571392a487219B98395106234c6c0Be3732796", - X: "7b1ede24b623def02bc86e32702a4b1afd8dd31586e87f6d87887f3391c7bd6e", - Y: "347a62abfdbb488e5710eab49e1b8e88c3164d92a0095eaf8d087120a03baa59", - }, - metadata: { - pubNonce: { - X: "5e1b1653f2fa15da37d94a052be4e6ef37cd8bf9f5d4a10f1742e6a03134acac", - Y: "3a12ed5ac3ca5ca7ad056edc9ea6a16498b93c7a2669044d0154527a22c7dd5a", - }, - nonce: new BN("0"), + nonce: new BN("0", "hex"), upgraded: false, typeOfUser: "v2", }, @@ -330,31 +275,31 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); }); it("should be able to login when verifierID hash enabled", async function () { - const token = generateIdToken(TORUS_TEST_EMAIL, "ES256"); - const verifierDetails = { verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL }; - - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); + const testEmail = TORUS_TEST_EMAIL_HASHED; + const token = generateIdToken(testEmail, "ES256"); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: testEmail }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( torusNodeEndpoints, nodeDetails.torusIndexes, HashEnabledVerifier, - { verifier_id: TORUS_TEST_EMAIL }, + { verifier_id: testEmail }, token, nodeDetails.torusNodePub ); + delete result.metadata.serverTimeOffset; expect(result).eql({ finalKeyData: { - evmAddress: "0x86571392a487219B98395106234c6c0Be3732796", - X: "7b1ede24b623def02bc86e32702a4b1afd8dd31586e87f6d87887f3391c7bd6e", - Y: "347a62abfdbb488e5710eab49e1b8e88c3164d92a0095eaf8d087120a03baa59", - privKey: "01de90970e389675a64673fd38845304cbf0a00ea98c202db3d53210ec9a337c", + walletAddress: "74stJxXes7SP6T4uH2wRPiDQaeSc6dpEHdh1RtsFYsGQ", + X: "361660e9eb925988579d824ff6f4ea6cc8f35399b118f227ab233081aa72d50e", + Y: "3dbabd3baae7ad031e048d0b8f42efe1917d9291fd6a7d9476820dc04166245a", + privKey: "0e12e0192aeb716da5d836eec85a97b13e227843d7a897656c520c119f7eb4af5a246641c00d8276947d6afd91927d91e1ef428f0b8d041e03ade7aa3bbdba3d", }, oAuthKeyData: { - evmAddress: "0x2b133a232194524A421EB5A7BE8F5Ad7df25a02A", - X: "299ad86ffe85fb33d8eee765908a031ae543af09f5226316d2367aa6d21df9af", - Y: "45d153c52d8b1eb12c2e2b5769284a4763ca7d61d8373f109d1997b6c647742b", - privKey: "0db22507f8262d2b76cbb3bac9ac9e9e67fae25981f2b8091bd5e825b34e100b", + walletAddress: "FucMH9d3YMJD2qh2ums4Xqfw5Htc8PR6pYUzQnr2xgmK", + X: "161da0ab7a991abb8981968de76652880f09e479d1df4a15e5f4b537d244f1a5", + Y: "0effa9486c130b7e25e4181023c92ea69f1ee0ee835a0735bd7b446cfbc97ddd", + privKey: "0bd77284601dbc3a5c0c6f9829f4d0d0f2d87d439014042b13953724e4d49db8", }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, @@ -362,10 +307,10 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }, metadata: { pubNonce: { - X: "5e1b1653f2fa15da37d94a052be4e6ef37cd8bf9f5d4a10f1742e6a03134acac", - Y: "3a12ed5ac3ca5ca7ad056edc9ea6a16498b93c7a2669044d0154527a22c7dd5a", + X: "51b5cc6c5d917b97b28f0472bde7b04f67a1ce6745cd374d2586cc088a49b887", + Y: "39e4d6c342716e1bd9fca5553714d3e147a148c2b1eba5a77207db4a3246c205", }, - nonce: new BN("142c6b8f1612694a2f7ac0426ed7b4668db3b1726d88a1d14824101ff337cb4b", "hex"), + nonce: new BN("7bad1284d129014a24737a275021085c1789b03d5b7ee37d1f7a47eeb23877f", "hex"), typeOfUser: "v2", upgraded: false, }, @@ -373,6 +318,19 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); }); + // to do: update pub keys + it.skip("should lookup return hash when verifierID hash enabled", async function () { + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_VERIFIER }); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + for (const endpoint of torusNodeEndpoints) { + const pubKeyX = "21cd0ae3168d60402edb8bd65c58ff4b3e0217127d5bb5214f03f84a76f24d8a"; + const pubKeyY = "575b7a4d0ef9921b3b1b84f30d412e87bc69b4eab83f6706e247cceb9e985a1e"; + const response = await lookupVerifier(endpoint, pubKeyX, pubKeyY); + const verifierID = response.result.verifiers[HashEnabledVerifier][0]; + expect(verifierID).to.equal("086c23ab78578f2fce9a1da11c0071ec7c2225adb1bf499ffaee98675bee29b7"); + } + }); + it("should be able to aggregate login", async function () { const email = faker.internet.email(); const idToken = generateIdToken(email, "ES256"); @@ -393,9 +351,9 @@ describe.only("torus utils ed25519 sapphire devnet", function () { hashedIdToken.substring(2), nodeDetails.torusNodePub ); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.not.equal(null); expect(result.metadata.upgraded).to.equal(false); diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index efe4a3b..d522d14 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -32,18 +32,18 @@ describe("torus utils sapphire mainnet", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0x327b2742768B436d09153429E762FADB54413Ded"); + expect(result.finalKeyData.walletAddress).to.equal("0x327b2742768B436d09153429E762FADB54413Ded"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b", + walletAddress: "0xb1a49C6E50a1fC961259a8c388EAf5953FA5152b", X: "a9f5a463aefb16e90f4cbb9de4a5b6b7f6c6a3831cefa0f20cccb9e7c7b01c20", Y: "3376c6734da57ab3a67c7792eeea20707d16992dd2c827a59499f4c056b00d08", }, finalKeyData: { - evmAddress: "0x327b2742768B436d09153429E762FADB54413Ded", + walletAddress: "0x327b2742768B436d09153429E762FADB54413Ded", X: "1567e030ca76e520c180c50bc6baed07554ebc35c3132495451173e9310d8be5", Y: "123c0560757ffe6498bf2344165d0f295ea74eb8884683675e5f17ae7bb41cdb", }, @@ -86,10 +86,10 @@ describe("torus utils sapphire mainnet", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v2"); expect(metadata.upgraded).to.equal(false); }); @@ -103,8 +103,8 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(false); @@ -119,18 +119,18 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.be.equal("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", + walletAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", X: "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29", Y: "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb", }, finalKeyData: { - evmAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", + walletAddress: "0x98EC5b049c5C0Dc818C69e95CF43534AEB80261A", X: "a772c71ca6c650506f26a180456a6bdf462996781a10f1740f4e65314f360f29", Y: "776c2178ff4620c67197b2f26b1222503919ff26a7cbd0fdbc91a2c9764e56cb", }, @@ -161,7 +161,7 @@ describe("torus utils sapphire mainnet", function () { nodeDetails.torusNodePub ); expect(result.finalKeyData.privKey).to.not.equal(null); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); @@ -172,18 +172,18 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); + expect(result.finalKeyData.walletAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", }, finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", }, @@ -205,17 +205,17 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); + expect(result.finalKeyData.walletAddress).to.equal("0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB"); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", }, finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", }, @@ -251,13 +251,13 @@ describe("torus utils sapphire mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", + walletAddress: "0xCb76F4C8cbAe524997787B57efeeD99f6D3BD5AB", X: "b943bfdc29c515195270d3a219da6a57bcaf6e58e57d03e2accb8c716e6949c8", Y: "a0fe9ac87310d302a821f89a747d80c9b7dc5cbd0956571f84b09e58d11eee90", privKey: "13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6", }, oAuthKeyData: { - evmAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", + walletAddress: "0xeBe48BE7693a36Ff562D18c4494AC4496A45EaaC", X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", privKey: "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478", @@ -298,13 +298,13 @@ describe("torus utils sapphire mainnet", function () { expect(result).eql({ finalKeyData: { - evmAddress: "0x70520A7F04868ACad901683699Fa32765C9F6871", + walletAddress: "0x70520A7F04868ACad901683699Fa32765C9F6871", X: "adff099b5d3b1e238b43fba1643cfa486e8d9e8de22c1e6731d06a5303f9025b", Y: "21060328e7889afd303acb63201b6493e3061057d1d81279931ab4a6cabf94d4", privKey: "dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419", }, oAuthKeyData: { - evmAddress: "0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673", + walletAddress: "0x925c97404F1aBdf4A8085B93edC7B9F0CEB3C673", X: "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d", Y: "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391", privKey: "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906", @@ -343,9 +343,9 @@ describe("torus utils sapphire mainnet", function () { hashedIdToken.substring(2), nodeDetails.torusNodePub ); - expect(result.finalKeyData.evmAddress).to.not.equal(null); - expect(result.finalKeyData.evmAddress).to.not.equal(""); - expect(result.oAuthKeyData.evmAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(null); + expect(result.finalKeyData.walletAddress).to.not.equal(""); + expect(result.oAuthKeyData.walletAddress).to.not.equal(null); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.not.equal(null); expect(result.metadata.upgraded).to.equal(false); diff --git a/test/testnet.test.ts b/test/testnet.test.ts index 30f311f..fc7cd76 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -29,18 +29,18 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result.finalKeyData.evmAddress).to.equal("0x9bcBAde70546c0796c00323CD1b97fa0a425A506"); + expect(result.finalKeyData.walletAddress).to.equal("0x9bcBAde70546c0796c00323CD1b97fa0a425A506"); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, finalKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, @@ -59,7 +59,7 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result1 = await torus.getUserTypeAndAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(result1.finalKeyData.evmAddress).to.equal("0xf5804f608C233b9cdA5952E46EB86C9037fd6842"); + expect(result1.finalKeyData.walletAddress).to.equal("0xf5804f608C233b9cdA5952E46EB86C9037fd6842"); expect(result1.metadata.typeOfUser).to.equal("v2"); expect(result1.metadata.serverTimeOffset).lessThan(20); @@ -67,12 +67,12 @@ describe("torus utils migrated testnet on sapphire", function () { expect(result1).eql({ oAuthKeyData: { - evmAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", + walletAddress: "0x9bcBAde70546c0796c00323CD1b97fa0a425A506", X: "894f633b3734ddbf08867816bc55da60803c1e7c2a38b148b7fb2a84160a1bb5", Y: "1cf2ea7ac63ee1a34da2330413692ba8538bf7cd6512327343d918e0102a1438", }, finalKeyData: { - evmAddress: "0xf5804f608C233b9cdA5952E46EB86C9037fd6842", + walletAddress: "0xf5804f608C233b9cdA5952E46EB86C9037fd6842", X: "ed737569a557b50722a8b5c0e4e5ca30cef1ede2f5674a0616b78246bb93dfd0", Y: "d9e8e6c54c12c4da38c2f0d1047fcf6089036127738f4ef72a83431339586ca9", }, @@ -95,7 +95,7 @@ describe("torus utils migrated testnet on sapphire", function () { verifier: v2Verifier, verifierId: v2TestEmail, })) as TorusPublicKey; - expect(result2.finalKeyData.evmAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); + expect(result2.finalKeyData.walletAddress).to.equal("0xE91200d82029603d73d6E307DbCbd9A7D0129d8D"); expect(result2.metadata.typeOfUser).to.equal("v2"); expect(result2.metadata.serverTimeOffset).lessThan(20); @@ -103,12 +103,12 @@ describe("torus utils migrated testnet on sapphire", function () { expect(result2).eql({ oAuthKeyData: { - evmAddress: "0x376597141d8d219553378313d18590F373B09795", + walletAddress: "0x376597141d8d219553378313d18590F373B09795", X: "86cd2db15b7a9937fa8ab7d0bf8e7f4113b64d1f4b2397aad35d6d4749d2fb6c", Y: "86ef47a3724144331c31a3a322d85b6fc1a5d113b41eaa0052053b6e3c74a3e2", }, finalKeyData: { - evmAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", + walletAddress: "0xE91200d82029603d73d6E307DbCbd9A7D0129d8D", X: "c350e338dde24df986915992fea6e0aef3560c245ca144ee7fe1498784c4ef4e", Y: "a605e52b65d3635f89654519dfa7e31f7b45f206ef4189866ad0c2240d40f97f", }, @@ -130,18 +130,18 @@ describe("torus utils migrated testnet on sapphire", function () { verifier: v2Verifier, verifierId: v2nTestEmail, })) as TorusPublicKey; - expect(result3.finalKeyData.evmAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); + expect(result3.finalKeyData.walletAddress).to.equal("0x1016DA7c47A04C76036637Ea02AcF1d29c64a456"); expect(result3.metadata.typeOfUser).to.equal("v2"); delete result3.metadata.serverTimeOffset; expect(result3).eql({ oAuthKeyData: { - evmAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", + walletAddress: "0xd45383fbF04BccFa0450d7d8ee453ca86b7C6544", X: "d25cc473fbb448d20b5551f3c9aa121e1924b3d197353347187c47ad13ecd5d8", Y: "3394000f43160a925e6c3017dde1354ecb2b61739571c6584f58edd6b923b0f5", }, finalKeyData: { - evmAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", + walletAddress: "0x1016DA7c47A04C76036637Ea02AcF1d29c64a456", X: "d3e222f6b23f0436b7c86e9cc4164eb5ea8448e4c0e7539c8b4f7fd00e8ec5c7", Y: "1c47f5faccec6cf57c36919f6f0941fe3d8d65033cf2cc78f209304386044222", }, @@ -164,10 +164,10 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier, verifierId: email }; const { torusNodeEndpoints, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const { finalKeyData, oAuthKeyData, metadata } = await torus.getPublicAddress(torusNodeEndpoints, torusNodePub, verifierDetails); - expect(finalKeyData.evmAddress).to.not.equal(""); - expect(finalKeyData.evmAddress).to.not.equal(null); - expect(oAuthKeyData.evmAddress).to.not.equal(""); - expect(oAuthKeyData.evmAddress).to.not.equal(null); + expect(finalKeyData.walletAddress).to.not.equal(""); + expect(finalKeyData.walletAddress).to.not.equal(null); + expect(oAuthKeyData.walletAddress).to.not.equal(""); + expect(oAuthKeyData.walletAddress).to.not.equal(null); expect(metadata.typeOfUser).to.equal("v1"); expect(metadata.upgraded).to.equal(false); }); @@ -183,13 +183,13 @@ describe("torus utils migrated testnet on sapphire", function () { expect(result.finalKeyData.privKey).to.be.equal("9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3"); expect(result).eql({ finalKeyData: { - evmAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", + walletAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", }, oAuthKeyData: { - evmAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", + walletAddress: "0xF8d2d3cFC30949C1cb1499C9aAC8F9300535a8d6", X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", @@ -223,17 +223,17 @@ describe("torus utils migrated testnet on sapphire", function () { delete result.metadata.serverTimeOffset; expect(result.metadata.typeOfUser).to.be.equal("v1"); - expect(result.oAuthKeyData.evmAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); - expect(result.finalKeyData.evmAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); + expect(result.oAuthKeyData.walletAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); + expect(result.finalKeyData.walletAddress).to.be.equal("0x938a40E155d118BD31E439A9d92D67bd55317965"); expect(result).eql({ finalKeyData: { - evmAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", + walletAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", }, oAuthKeyData: { - evmAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", + walletAddress: "0x938a40E155d118BD31E439A9d92D67bd55317965", X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", From 855aca0d96f07c138ea99f07bee914788dee0c4e Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 20 Mar 2024 00:42:37 +0530 Subject: [PATCH 20/56] return pubkey in b58 --- src/helpers/metadataUtils.ts | 1 - src/helpers/nodeUtils.ts | 7 +++++-- src/torus.ts | 20 ++++++++++++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index a9f24b0..5fc6ef8 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -131,7 +131,6 @@ export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { const decryptionKey = getSecpKeyFromEd25519(finalUserKey); const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; - const bufferMetadata = { ephemPublicKey: Buffer.from(seedJson.metadata.ephemPublicKey, "hex"), iv: Buffer.from(seedJson.metadata.iv, "hex"), diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index c650bbd..2ba9f18 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -2,6 +2,7 @@ import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_N import { generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; +import base58 from "bs58"; import { curve, ec } from "elliptic"; import { config } from "../config"; @@ -214,7 +215,8 @@ export async function retrieveOrImportShare(params: { } finalImportedShares = newImportedShares; } else if (!useDkg) { - const importedKey = new BN(generatePrivateKey(ecCurve, Buffer)); + const bufferKey = generatePrivateKey(ecCurve, Buffer); + const importedKey = new BN(bufferKey); const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey); finalImportedShares = [...finalImportedShares, ...generatedShares]; } @@ -755,9 +757,10 @@ export async function retrieveOrImportShare(params: { if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); } else if (keyWithNonce && nonceResult.seed) { + // console.log("nonceResult.seed", nonceResult.seed, keyWithNonce); const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); const totalLength = decryptedSeed.length + encodedPubKey.length; - finalPrivKey = Buffer.concat([decryptedSeed, encodedPubKey], totalLength).toString("hex"); + finalPrivKey = base58.encode(Buffer.concat([decryptedSeed, encodedPubKey], totalLength)); } } else { throw new Error(`Invalid keyType: ${keyType}`); diff --git a/src/torus.ts b/src/torus.ts index 1175a88..4cfd587 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -6,10 +6,12 @@ import { SIGNER_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, + TORUS_SAPPHIRE_NETWORK, } from "@toruslabs/constants"; import { decrypt, generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post, setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; +import base58 from "bs58"; import { curve, ec as EC } from "elliptic"; import { config } from "./config"; @@ -84,7 +86,7 @@ class Torus { }: TorusCtorOptions) { if (!clientId) throw new Error("Please provide a valid clientId in constructor"); if (!network) throw new Error("Please provide a valid network in constructor"); - if (keyType === "ed25519" && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { + if (keyType === "ed25519" && network !== TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET) { throw new Error(`keyType: ${keyType} is not supported by ${network} network`); } this.keyType = keyType; @@ -220,13 +222,19 @@ class Torus { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } - const privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); + let privKeyBuffer; - if (this.keyType === "secp256k1" && privKeyBuffer.length !== 32) { - throw new Error("Invalid private key length for give secp256k1 key"); + if (this.keyType === "secp256k1") { + privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); + if (privKeyBuffer.length !== 32) { + throw new Error("Invalid private key length for given secp256k1 key"); + } } - if (this.keyType === "ed25519" && privKeyBuffer.length !== 64) { - throw new Error("Invalid private key length for give secp256k1 key"); + if (this.keyType === "ed25519") { + privKeyBuffer = Buffer.from(base58.decode(newPrivateKey)); + if (privKeyBuffer.length !== 64) { + throw new Error("Invalid private key length for given ed25519 key"); + } } const finalPrivKey = this.keyType === "secp256k1" ? privKeyBuffer : privKeyBuffer.slice(0, 32); From d9dab3109911038e0f663c4f71b18850947bf7e7 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 20 Mar 2024 01:10:06 +0530 Subject: [PATCH 21/56] fix tests --- src/helpers/nodeUtils.ts | 3 +- src/torus.ts | 4 +- test/sapphire_devnet_ed25519.test.ts | 86 +++++++++++++++------------- 3 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 2ba9f18..7f261f2 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -4,6 +4,7 @@ import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; import base58 from "bs58"; import { curve, ec } from "elliptic"; +import { getRandomBytes } from "ethereum-cryptography/random"; import { config } from "../config"; import { JRPC_METHODS } from "../constants"; @@ -215,7 +216,7 @@ export async function retrieveOrImportShare(params: { } finalImportedShares = newImportedShares; } else if (!useDkg) { - const bufferKey = generatePrivateKey(ecCurve, Buffer); + const bufferKey = keyType === "secp256k1" ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); const importedKey = new BN(bufferKey); const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey); finalImportedShares = [...finalImportedShares, ...generatedShares]; diff --git a/src/torus.ts b/src/torus.ts index 4cfd587..a47626f 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -237,11 +237,11 @@ class Torus { } } - const finalPrivKey = this.keyType === "secp256k1" ? privKeyBuffer : privKeyBuffer.slice(0, 32); + const finalPrivKey = this.keyType === "secp256k1" ? privKeyBuffer : privKeyBuffer.subarray(0, 32); const privKeyBn = new BN(finalPrivKey, 16); const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBn); if (this.keyType === "ed25519") { - const ed25519PubKey = privKeyBuffer.slice(32); + const ed25519PubKey = privKeyBuffer.subarray(32); const encodedPubKey = encodeEd25519Point(sharesData[0].final_user_point); const importedPubKey = Buffer.from(ed25519PubKey).toString("hex"); const derivedPubKey = encodedPubKey.toString("hex"); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 8b3c6bd..1560af9 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -9,7 +9,7 @@ import TorusUtils from "../src/torus"; import { generateIdToken, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "ed25519testuser@tor.us"; -const TORUS_TEST_EMAIL_HASHED = "ed25519testuserhash@tor.us"; +const TORUS_TEST_EMAIL_HASHED = "ed25519testuserhashed19@tor.us"; const TORUS_EXTENDED_VERIFIER_EMAIL = "testextenderverifierided25519@example.com"; @@ -34,27 +34,27 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); it("should should fetch public address", async function () { - const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk1@gmail.com" }; + const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Willa_Funk11@gmail.com" }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); - expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); + expect(result.finalKeyData.walletAddress).eql("HHmiJMCAwhyf9ZWNtj7FEKGXeeC2NjUjPobpDKm43yKs"); delete result.metadata.serverTimeOffset; expect(result).eql({ oAuthKeyData: { - walletAddress: "A5fzWVa6YDLpsZ3d8Zg6qwB9dLgGMw1UbtRctZeXy89n", - X: "175d1cb8a3fe85a6079d1d1892ef0421cc5f692ebda617bc61f1c8891b1fbcb6", - Y: "397d5c7c0c1f543d83c0a8be2d2824ca4298ff5b34714c2982dae82beb97eb86", + walletAddress: "49yLu8yLqpuCXchzjQSt1tpBz8AP2E9EzzP7a8QtxmTE", + X: "5d39eba90fafbce150b33b9a60b41e1cfdf9e2640b55bf96b787173d74f8e415", + Y: "099639b7da35c1f31a44da7399a29d7db8eaa9639582cf7ed80aa4f7216adf2e", }, finalKeyData: { - walletAddress: "3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM", - X: "664cf57e06afdbd897a8be4ce6e572bd836e306611597d30be31e6250571e87a", - Y: "4cf0a015e6b97a36f513025734a03d0ff429385574b04eb4a8db520f57137e24", + walletAddress: "HHmiJMCAwhyf9ZWNtj7FEKGXeeC2NjUjPobpDKm43yKs", + X: "575203523b34bcfa2c25c428871c421afd69dbcb7375833b52ef264aaa466a81", + Y: "26f0b1f5740088c2ecf676081b8e2fe5254f1cbb693947ae391af13500d706f2", }, metadata: { pubNonce: { - X: "439fe891f2f06a93f533aec3c2a1b0b247b7a6e52de4c8b943529e95224979b8", - Y: "51ed278447e030a8fca05362189f358c9d7eaff7818036b8c6c828e3eef40898", + X: "71bf997547c1ac3f0babee87ebac055e8542863ebb1ba66e8092499eacbffd22", + Y: "71a0a70c5ae06d7eeb45673d4081fdfc9f29c4acfbbb57bf52a33dd7630599b1", }, nonce: new BN("0", "hex"), typeOfUser: "v2", @@ -64,12 +64,11 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); }); it("should be able to import a key for a new user", async function () { - const email = "Willa_Funk1@gmail.com"; + const email = "Willa_Funk12@gmail.com"; const token = generateIdToken(email, "ES256"); // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); // key exported from phantom wallet - const privHex = - "0942c4f0dfe419364b716925e1138977b66844c96873aeaa02efb7bbc7d82628247e13570f52dba8b44eb074553829f40f3da034570213f5367ab9e615a0f04c"; + const privHex = "BjremmcjdFWexYJWcNSsT3U8ekuq6KnenBCSvxVfx2fQuvWbZQzDtQuAuXtQzcgxNY9CRyVNXJu2W5Rgt7ufQDh"; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( @@ -129,7 +128,7 @@ describe.only("torus utils ed25519 sapphire devnet", function () { walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", - privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f78363b2efd7cf8c4bba1c56a830404ee1841c9039f6f7a6359906e150c593c082f0", + privKey: "AV2s1hzK6xWHNPeSaaKiiJtgbDSjTx9LjDN9AtPhf3t7mAzxCjf9mDx25UzPrEHS8HcswFzSx4eSxCEEPmmyyEX", }, metadata: { pubNonce: { @@ -150,12 +149,22 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); it("should be able to key assign", async function () { const email = faker.internet.email(); + const token = generateIdToken(email, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); expect(result.finalKeyData.walletAddress).to.not.equal(""); expect(result.finalKeyData.walletAddress).to.not.equal(null); + const result2 = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub + ); + expect(result.finalKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); }); it("should be able to login even when node is down", async function () { @@ -171,9 +180,7 @@ describe.only("torus utils ed25519 sapphire devnet", function () { token, nodeDetails.torusNodePub ); - expect(result.finalKeyData.privKey).to.be.equal( - "ea39cc89d2d8b8403858d1c518fe82e2500cc83e472ba86d006323b57835a5197139cf3a4c9b145471ac5efcdcbeab630bfa7a387e672b4940f18d686effa30f" - ); + expect(result.finalKeyData.privKey).to.be.equal("5gcMa5vaPupHmFbDLeQR14odwCke5W3pF9y92BuLjFSACKuyNNCAEYfh3yZ7KyVJpZsjjpwZpneshfzB5ae6P89c"); }); it("should fetch pub address of tss verifier id", async function () { @@ -251,21 +258,22 @@ describe.only("torus utils ed25519 sapphire devnet", function () { const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); delete result.metadata.serverTimeOffset; + expect(result).eql({ oAuthKeyData: { - walletAddress: "FucMH9d3YMJD2qh2ums4Xqfw5Htc8PR6pYUzQnr2xgmK", - X: "161da0ab7a991abb8981968de76652880f09e479d1df4a15e5f4b537d244f1a5", - Y: "0effa9486c130b7e25e4181023c92ea69f1ee0ee835a0735bd7b446cfbc97ddd", + walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", + X: "45c531429896ab89078789018b21639dab308b7d3952d9df243177e60fc0eb1f", + Y: "6155cf9bb00f8eedf398361c2140a5ed3fe2b3c51b883e757addcb06e09bcbc0", }, finalKeyData: { - walletAddress: "74stJxXes7SP6T4uH2wRPiDQaeSc6dpEHdh1RtsFYsGQ", - X: "361660e9eb925988579d824ff6f4ea6cc8f35399b118f227ab233081aa72d50e", - Y: "3dbabd3baae7ad031e048d0b8f42efe1917d9291fd6a7d9476820dc04166245a", + walletAddress: "HK9Xo2UgjuMNxBi6WxX76hfQm9oTtJdDUSGKFhzGQiSo", + X: "6002549f42c1f3504652ce4b3fb1cbff4f1eaa1b66551313dd9c44d48b31a63d", + Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", }, metadata: { pubNonce: { - X: "51b5cc6c5d917b97b28f0472bde7b04f67a1ce6745cd374d2586cc088a49b887", - Y: "39e4d6c342716e1bd9fca5553714d3e147a148c2b1eba5a77207db4a3246c205", + X: "4cc875975c4ed6fed34758eab0be8954c50decbe736f85b3c5011f5035dd9e27", + Y: "233fe212cf0d6033be989f9dd5ffd5dfe77f0c3340984fcc5b0dd745bdfded12", }, nonce: new BN("0", "hex"), upgraded: false, @@ -277,29 +285,29 @@ describe.only("torus utils ed25519 sapphire devnet", function () { it("should be able to login when verifierID hash enabled", async function () { const testEmail = TORUS_TEST_EMAIL_HASHED; const token = generateIdToken(testEmail, "ES256"); - const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: testEmail }); + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL_HASHED }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( torusNodeEndpoints, nodeDetails.torusIndexes, HashEnabledVerifier, - { verifier_id: testEmail }, + { verifier_id: TORUS_TEST_EMAIL_HASHED }, token, nodeDetails.torusNodePub ); delete result.metadata.serverTimeOffset; expect(result).eql({ finalKeyData: { - walletAddress: "74stJxXes7SP6T4uH2wRPiDQaeSc6dpEHdh1RtsFYsGQ", - X: "361660e9eb925988579d824ff6f4ea6cc8f35399b118f227ab233081aa72d50e", - Y: "3dbabd3baae7ad031e048d0b8f42efe1917d9291fd6a7d9476820dc04166245a", - privKey: "0e12e0192aeb716da5d836eec85a97b13e227843d7a897656c520c119f7eb4af5a246641c00d8276947d6afd91927d91e1ef428f0b8d041e03ade7aa3bbdba3d", + walletAddress: "HK9Xo2UgjuMNxBi6WxX76hfQm9oTtJdDUSGKFhzGQiSo", + X: "6002549f42c1f3504652ce4b3fb1cbff4f1eaa1b66551313dd9c44d48b31a63d", + Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", + privKey: "2SDsHqpEGTszmk73SyFu1tR85bK2kt7HmnBercBSiBZpHpYHBiqpquG8ARhRuDWXGquTM7NVRva3xFMSJ8sd2aQ3", }, oAuthKeyData: { - walletAddress: "FucMH9d3YMJD2qh2ums4Xqfw5Htc8PR6pYUzQnr2xgmK", - X: "161da0ab7a991abb8981968de76652880f09e479d1df4a15e5f4b537d244f1a5", - Y: "0effa9486c130b7e25e4181023c92ea69f1ee0ee835a0735bd7b446cfbc97ddd", - privKey: "0bd77284601dbc3a5c0c6f9829f4d0d0f2d87d439014042b13953724e4d49db8", + walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", + X: "45c531429896ab89078789018b21639dab308b7d3952d9df243177e60fc0eb1f", + Y: "6155cf9bb00f8eedf398361c2140a5ed3fe2b3c51b883e757addcb06e09bcbc0", + privKey: "0423cd18b36b862054489ad706d9be0226204af69b0407907dc1f3ee9ca72b7a", }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, @@ -307,10 +315,10 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }, metadata: { pubNonce: { - X: "51b5cc6c5d917b97b28f0472bde7b04f67a1ce6745cd374d2586cc088a49b887", - Y: "39e4d6c342716e1bd9fca5553714d3e147a148c2b1eba5a77207db4a3246c205", + X: "4cc875975c4ed6fed34758eab0be8954c50decbe736f85b3c5011f5035dd9e27", + Y: "233fe212cf0d6033be989f9dd5ffd5dfe77f0c3340984fcc5b0dd745bdfded12", }, - nonce: new BN("7bad1284d129014a24737a275021085c1789b03d5b7ee37d1f7a47eeb23877f", "hex"), + nonce: new BN("8ff7137ce3f5648b8722779e0d3c153bf76042800783bd6793f38672d8c129d", "hex"), typeOfUser: "v2", upgraded: false, }, From 3107b9998eceb70888120ab46acc473186599116 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 20 Mar 2024 15:20:58 +0530 Subject: [PATCH 22/56] package lock updated --- package-lock.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package-lock.json b/package-lock.json index d2482c7..ff65839 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2298,6 +2298,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/@noble/curves": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", + "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", + "dependencies": { + "@noble/hashes": "1.3.3" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/hashes": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", From 02bb409507dfc2f40bdfa3a89bc458ffcdeb2f54 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 20 Mar 2024 15:47:51 +0530 Subject: [PATCH 23/56] 13.0.0-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff65839..a6b860a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "12.2.0", + "version": "13.0.0-alpha.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "12.2.0", + "version": "13.0.0-alpha.0", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.2.0", diff --git a/package.json b/package.json index fff8ec5..c7b495a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "12.2.0", + "version": "13.0.0-alpha.0", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 802f9fca04bab60e402e0dafdb4d2eb9932d9486 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 20 Mar 2024 15:51:17 +0530 Subject: [PATCH 24/56] Release 13.0.0-alpha.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a6b860a..5c274a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.0", + "version": "13.0.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.0", + "version": "13.0.0-alpha.1", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.2.0", diff --git a/package.json b/package.json index c7b495a..ef1f084 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.0", + "version": "13.0.0-alpha.1", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 04c151cf3c86b079e216f334789eca262aeaa3b1 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 4 Apr 2024 11:26:36 +0530 Subject: [PATCH 25/56] fix metadata signing key for ed25519 --- src/helpers/keyUtils.ts | 7 +- src/helpers/metadataUtils.ts | 98 ++++++++++++++++++---------- src/interfaces.ts | 4 +- test/sapphire_devnet_ed25519.test.ts | 2 +- 4 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 6080f79..6f40635 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -118,14 +118,15 @@ export const generateEd25519KeyData = async (ed25519Seed: BN): Promise { - let data: Data; - const msg = getOnly ? "getNonce" : "getOrSetNonce"; - if (privKey) { - data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey); - } else { - data = { - pub_key_X: X, - pub_key_Y: Y, - set_data: { data: msg }, - }; - } - return post(`${legacyMetadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); -} - -export async function getNonce( - legacyMetadataHost: string, - ecCurve: ec, - serverTimeOffset: number, - X: string, - Y: string, - privKey?: BN -): Promise { - return getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, X, Y, privKey, true); -} - export function generateNonceMetadataParams( serverTimeOffset: number, operation: string, @@ -126,6 +92,70 @@ export function generateNonceMetadataParams( }; } +export async function getOrSetNonce( + metadataHost: string, + ecCurve: ec, + serverTimeOffset: number, + X: string, + Y: string, + privKey?: BN, + getOnly = false, + isLegacyMetadata = true, + nonce = new BN(0), + keyType: KeyType = "secp256k1", + seed = "" +): Promise { + // for legacy metadata + if (isLegacyMetadata) { + let data: Data; + const msg = getOnly ? "getNonce" : "getOrSetNonce"; + if (privKey) { + data = generateMetadataParams(ecCurve, serverTimeOffset, msg, privKey); + } else { + data = { + pub_key_X: X, + pub_key_Y: Y, + set_data: { data: msg }, + }; + } + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); + } + + // for sapphire metadata + const operation = getOnly ? "getNonce" : "getOrSetNonce"; + if (operation === "getOrSetNonce") { + if (!privKey) { + throw new Error("privKey is required while `getOrSetNonce` for non legacy metadata"); + } + if (nonce.cmp(new BN(0)) === 0) { + throw new Error("nonce is required while `getOrSetNonce` for non legacy metadata"); + } + if (keyType === "ed25519" && !seed) { + throw new Error("seed is required while `getOrSetNonce` for non legacy metadata for ed25519 key type"); + } + const data = generateNonceMetadataParams(serverTimeOffset, operation, privKey, keyType, nonce, seed); + + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); + } + const data = { + pub_key_X: X, + pub_key_Y: Y, + set_data: { operation: "getNonce" }, + key_type: keyType, + }; + return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); +} +export async function getNonce( + legacyMetadataHost: string, + ecCurve: ec, + serverTimeOffset: number, + X: string, + Y: string, + privKey?: BN +): Promise { + return getOrSetNonce(legacyMetadataHost, ecCurve, serverTimeOffset, X, Y, privKey, true); +} + export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { const decryptionKey = getSecpKeyFromEd25519(finalUserKey); const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); diff --git a/src/interfaces.ts b/src/interfaces.ts index 0767444..32c1470 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -263,9 +263,9 @@ export interface PrivateKeyData { SigningPubX: BN; SigningPubY: BN; metadataNonce: BN; - encryptedSeed?: string; + metadataSigningKey: BN; finalUserPubKeyPoint: curve.base.BasePoint; - metadataSigningKey?: BN; + encryptedSeed?: string; } export interface EncryptedSeed { diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 72832d2..ab451c5 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -65,7 +65,7 @@ describe("torus utils ed25519 sapphire devnet", function () { }); it("should be able to import a key for a new user", async function () { - const email = "Willa_Funk12@gmail.com"; + const email = "Willa_Funk1289@gmail.com"; const token = generateIdToken(email, "ES256"); // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); // key exported from phantom wallet From 0acead95072ce57ba46f4c14108ab3921d2eeca4 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 4 Apr 2024 11:35:58 +0530 Subject: [PATCH 26/56] Release 13.0.0-alpha.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5c274a1..adf8e28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.1", + "version": "13.0.0-alpha.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.1", + "version": "13.0.0-alpha.2", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.2.0", diff --git a/package.json b/package.json index ef1f084..7d6a7f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.1", + "version": "13.0.0-alpha.2", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 5252dffacfaeacf17c95defbc2e35d91c5bf97b8 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 4 Apr 2024 13:25:06 +0530 Subject: [PATCH 27/56] return final ed25519 key in seed hex format --- src/helpers/keyUtils.ts | 12 ++++++------ src/helpers/nodeUtils.ts | 19 +++---------------- src/torus.ts | 13 ++++++------- test/sapphire_devnet_ed25519.test.ts | 18 +++++++++++------- 4 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 6f40635..a08c04f 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -56,14 +56,13 @@ function adjustScalarBytes(bytes: Buffer): Buffer { } /** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */ -export function getEd25519ExtendedPublicKey(keyHex: BN): { +export function getEd25519ExtendedPublicKey(keyBuffer: Buffer): { scalar: BN; point: curve.base.BasePoint; } { const len = 32; const G = ed25519Curve.g; const N = ed25519Curve.n; - const keyBuffer = keyHex.toArrayLike(Buffer); if (keyBuffer.length !== 32) { log.error("Invalid seed for ed25519 key derivation", keyBuffer.length); @@ -104,10 +103,10 @@ export function encodeEd25519Point(point: curve.base.BasePoint) { return enc; } -export const generateEd25519KeyData = async (ed25519Seed: BN): Promise => { +export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise => { const finalEd25519Key = getEd25519ExtendedPublicKey(ed25519Seed); const encryptionKey = getSecpKeyFromEd25519(finalEd25519Key.scalar); - const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed.toArrayLike(Buffer)); + const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed); const encData: EncryptedSeed = { enc_text: encryptedSeed.ciphertext.toString("hex"), metadata: encParamsBufToHex(encryptedSeed), @@ -132,7 +131,8 @@ export const generateEd25519KeyData = async (ed25519Seed: BN): Promise => { +export const generateSecp256k1KeyData = async (scalarBuffer: Buffer): Promise => { + const scalar = new BN(scalarBuffer); const randomNonce = new BN(generatePrivateKey(secp256k1Curve, Buffer)); const oAuthKey = scalar.sub(randomNonce).umod(secp256k1Curve.curve.n); const oAuthKeyPair = secp256k1Curve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")); @@ -202,7 +202,7 @@ export const generateShares = async ( serverTimeOffset: number, nodeIndexes: number[], nodePubkeys: INodePub[], - privKey: BN + privKey: Buffer ) => { const keyData = keyType === "ed25519" ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); const { metadataNonce, oAuthKeyScalar: oAuthKey, encryptedSeed, metadataSigningKey } = keyData; diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index cd2340c..97ebec9 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -2,7 +2,6 @@ import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_N import { generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; -import base58 from "bs58"; import { curve, ec } from "elliptic"; import { getRandomBytes } from "ethereum-cryptography/random"; @@ -38,15 +37,7 @@ import { normalizeLegacyKeysResult, thresholdSame, } from "./common"; -import { - derivePubKey, - encodeEd25519Point, - generateAddressFromPrivKey, - generateAddressFromPubKey, - generatePrivateKey, - generateShares, - keccak256, -} from "./keyUtils"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generatePrivateKey, generateShares, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, decryptSeedData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -217,8 +208,7 @@ export async function retrieveOrImportShare(params: { finalImportedShares = newImportedShares; } else if (!useDkg) { const bufferKey = keyType === "secp256k1" ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); - const importedKey = new BN(bufferKey); - const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, importedKey); + const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, Buffer.from(bufferKey)); finalImportedShares = [...finalImportedShares, ...generatedShares]; } @@ -745,15 +735,12 @@ export async function retrieveOrImportShare(params: { if (keyType === "secp256k1") { finalPrivKey = keyWithNonce; } else if (keyType === "ed25519") { - const finalPubKeyPair = ecCurve.keyFromPublic({ x: finalPubKey.getX().toString("hex"), y: finalPubKey.getY().toString("hex") }); - const encodedPubKey = encodeEd25519Point(finalPubKeyPair.getPublic()); if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); } else if (keyWithNonce && nonceResult.seed) { // console.log("nonceResult.seed", nonceResult.seed, keyWithNonce); const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); - const totalLength = decryptedSeed.length + encodedPubKey.length; - finalPrivKey = base58.encode(Buffer.concat([decryptedSeed, encodedPubKey], totalLength)); + finalPrivKey = decryptedSeed.toString("hex"); } } else { throw new Error(`Invalid keyType: ${keyType}`); diff --git a/src/torus.ts b/src/torus.ts index 25c5608..d9c2e44 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -11,7 +11,6 @@ import { import { decrypt, generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post, setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; -import base58 from "bs58"; import { curve, ec as EC } from "elliptic"; import { config } from "./config"; @@ -22,6 +21,7 @@ import { generateAddressFromPrivKey, generateAddressFromPubKey, generateShares, + getEd25519ExtendedPublicKey, getMetadata, getNonce, getOrSetNonce, @@ -234,17 +234,16 @@ class Torus { } } if (this.keyType === "ed25519") { - privKeyBuffer = Buffer.from(base58.decode(newPrivateKey)); - if (privKeyBuffer.length !== 64) { + privKeyBuffer = Buffer.from(newPrivateKey, "hex"); + if (privKeyBuffer.length !== 32) { throw new Error("Invalid private key length for given ed25519 key"); } } - const finalPrivKey = this.keyType === "secp256k1" ? privKeyBuffer : privKeyBuffer.subarray(0, 32); - const privKeyBn = new BN(finalPrivKey, 16); - const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBn); + const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBuffer); if (this.keyType === "ed25519") { - const ed25519PubKey = privKeyBuffer.subarray(32); + const ed25519Key = getEd25519ExtendedPublicKey(privKeyBuffer); + const ed25519PubKey = encodeEd25519Point(ed25519Key.point); const encodedPubKey = encodeEd25519Point(sharesData[0].final_user_point); const importedPubKey = Buffer.from(ed25519PubKey).toString("hex"); const derivedPubKey = encodedPubKey.toString("hex"); diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index ab451c5..8c1af13 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -1,6 +1,7 @@ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; import NodeManager from "@toruslabs/fetch-node-details"; import BN from "bn.js"; +import base58 from "bs58"; import { expect } from "chai"; import faker from "faker"; @@ -69,9 +70,12 @@ describe("torus utils ed25519 sapphire devnet", function () { const token = generateIdToken(email, "ES256"); // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); // key exported from phantom wallet - const privHex = "BjremmcjdFWexYJWcNSsT3U8ekuq6KnenBCSvxVfx2fQuvWbZQzDtQuAuXtQzcgxNY9CRyVNXJu2W5Rgt7ufQDh"; + const privB58 = "BjremmcjdFWexYJWcNSsT3U8ekuq6KnenBCSvxVfx2fQuvWbZQzDtQuAuXtQzcgxNY9CRyVNXJu2W5Rgt7ufQDh"; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; + + const decodedKey = Buffer.from(base58.decode(privB58)); + const seedKey = decodedKey.subarray(0, 32).toString("hex"); const result = await torus.importPrivateKey( torusNodeEndpoints, nodeDetails.torusIndexes, @@ -79,10 +83,10 @@ describe("torus utils ed25519 sapphire devnet", function () { TORUS_TEST_VERIFIER, { verifier_id: email }, token, - privHex + seedKey ); expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); - expect(result.finalKeyData.privKey).to.be.equal(privHex); + expect(result.finalKeyData.privKey).to.be.equal(seedKey); const token1 = generateIdToken(email, "ES256"); const result1 = await torus.retrieveShares( @@ -94,7 +98,7 @@ describe("torus utils ed25519 sapphire devnet", function () { nodeDetails.torusNodePub ); expect(result1.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); - expect(result.finalKeyData.privKey).to.be.equal(privHex); + expect(result.finalKeyData.privKey).to.be.equal(seedKey); const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, @@ -130,7 +134,7 @@ describe("torus utils ed25519 sapphire devnet", function () { walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", - privKey: "AV2s1hzK6xWHNPeSaaKiiJtgbDSjTx9LjDN9AtPhf3t7mAzxCjf9mDx25UzPrEHS8HcswFzSx4eSxCEEPmmyyEX", + privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f783", }, metadata: { pubNonce: { @@ -205,7 +209,7 @@ describe("torus utils ed25519 sapphire devnet", function () { token, nodeDetails.torusNodePub ); - expect(result.finalKeyData.privKey).to.be.equal("5gcMa5vaPupHmFbDLeQR14odwCke5W3pF9y92BuLjFSACKuyNNCAEYfh3yZ7KyVJpZsjjpwZpneshfzB5ae6P89c"); + expect(result.finalKeyData.privKey).to.be.equal("ea39cc89d2d8b8403858d1c518fe82e2500cc83e472ba86d006323b57835a519"); }); it("should fetch pub address of tss verifier id", async function () { @@ -328,7 +332,7 @@ describe("torus utils ed25519 sapphire devnet", function () { walletAddress: "HK9Xo2UgjuMNxBi6WxX76hfQm9oTtJdDUSGKFhzGQiSo", X: "6002549f42c1f3504652ce4b3fb1cbff4f1eaa1b66551313dd9c44d48b31a63d", Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", - privKey: "2SDsHqpEGTszmk73SyFu1tR85bK2kt7HmnBercBSiBZpHpYHBiqpquG8ARhRuDWXGquTM7NVRva3xFMSJ8sd2aQ3", + privKey: "47c471c6c3b53f751e39feae967359b9258a790a30f2db394625f76b0c84ada0", }, oAuthKeyData: { walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", From a9119481f0076f42524aa668ee6829f350fb8468 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 4 Apr 2024 13:28:06 +0530 Subject: [PATCH 28/56] Release 13.0.0-alpha.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index adf8e28..8faee75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.2", + "version": "13.0.0-alpha.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.2", + "version": "13.0.0-alpha.3", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.2.0", diff --git a/package.json b/package.json index 7d6a7f0..335034a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.2", + "version": "13.0.0-alpha.3", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 5fd555d2a1285b552468a0a45e3a89a543288000 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 23 Apr 2024 11:26:18 +0530 Subject: [PATCH 29/56] fix retrieve shares for test tss verifier --- src/helpers/nodeUtils.ts | 1 + test/sapphire_devnet_ed25519.test.ts | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 97ebec9..213ba74 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -235,6 +235,7 @@ export async function retrieveOrImportShare(params: { temppuby: pubKeyY, verifieridentifier: verifier, verifier_id: verifierParams.verifier_id, + extended_verifier_id: verifierParams.extended_verifier_id, is_import_key_flow: true, }), null, diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 8c1af13..c00ec38 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -280,6 +280,27 @@ describe("torus utils ed25519 sapphire devnet", function () { expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.nonce).to.eql(new BN("0")); expect(result.metadata.upgraded).to.equal(true); + const token2 = generateIdToken(email, "ES256"); + + const result2 = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token2, + nodeDetails.torusNodePub + ); + expect(result.finalKeyData.privKey).to.equal(result2.finalKeyData.privKey); + expect(result.oAuthKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); + expect(result2.metadata.typeOfUser).to.equal(result.metadata.typeOfUser); + expect(result2.metadata.upgraded).to.equal(result.metadata.upgraded); + + const result3 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: email, + extendedVerifierId: tssVerifierId, + }); + expect(result3.oAuthKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); }); it("should fetch public address when verifierID hash enabled", async function () { From 48cf35051987e33fc6b832b0cc12a11f4f6e36c6 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 23 Apr 2024 11:33:45 +0530 Subject: [PATCH 30/56] Release 13.0.0-alpha.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8faee75..709f52a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.3", + "version": "13.0.0-alpha.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.3", + "version": "13.0.0-alpha.4", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.2.0", diff --git a/package.json b/package.json index 335034a..8774124 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.3", + "version": "13.0.0-alpha.4", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 6b5261fd61cc3ad426aa807be265ea6863e1c8c1 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 30 Apr 2024 16:39:25 +0530 Subject: [PATCH 31/56] retry decryption with unpadded cipher txt --- src/helpers/metadataUtils.ts | 17 +++++++++++++++++ src/helpers/nodeUtils.ts | 7 +++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index ab6e1e9..51c6e9e 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -25,6 +25,23 @@ export async function decryptNodeData(eciesData: EciesHex, ciphertextHex: string return decryptedSigBuffer; } +export async function decryptNodeDataWithPadding(eciesData: EciesHex, ciphertextHex: string, privKey: Buffer): Promise { + const ciphertextHexPadding = ciphertextHex.padStart(64, "0"); + const metadata = encParamsHexToBuf(eciesData); + + try { + const decryptedSigBuffer = await decrypt(privKey, { + ...metadata, + ciphertext: Buffer.from(ciphertextHexPadding, "hex"), + }); + return decryptedSigBuffer; + } catch (error) { + log.warn("Failed to decrypt padded share cipher", error); + // try without cipher text padding + return decrypt(privKey, { ...metadata, ciphertext: Buffer.from(ciphertextHex, "hex") }); + } +} + export function generateMetadataParams(ecCurve: ec, serverTimeOffset: number, message: string, privateKey: BN): MetadataParams { const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); const setData = { diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 213ba74..45ede9d 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -39,7 +39,7 @@ import { } from "./common"; import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generatePrivateKey, generateShares, keccak256 } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; -import { decryptNodeData, decryptSeedData, getMetadata, getOrSetNonce } from "./metadataUtils"; +import { decryptNodeData, decryptNodeDataWithPadding, decryptSeedData, getMetadata, getOrSetNonce } from "./metadataUtils"; export const GetPubKeyOrKeyAssign = async (params: { endpoints: string[]; @@ -548,12 +548,11 @@ export async function retrieveOrImportShare(params: { if (keys?.length > 0) { const latestKey = currentShareResponse.result.keys[0]; nodeIndexes.push(new BN(latestKey.node_index)); - if (latestKey.share_metadata) { sharePromises.push( - decryptNodeData( + decryptNodeDataWithPadding( latestKey.share_metadata, - Buffer.from(latestKey.share, "base64").toString("binary").padStart(64, "0"), + Buffer.from(latestKey.share, "base64").toString("binary"), sessionAuthKey ).catch((err) => log.error("share decryption", err)) ); From 37f69ca24caeb5f7dbb051ed2893285e4e02b889 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 30 Apr 2024 16:43:51 +0530 Subject: [PATCH 32/56] skip celeste tests because of recent migration --- test/celeste.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/celeste.test.ts b/test/celeste.test.ts index d5b962f..d59ae3d 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe("torus utils celeste", function () { +describe.skip("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; From b55aabafe7fa67ae7d1695fad0a4d92e7781e45d Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 2 May 2024 09:16:49 +0530 Subject: [PATCH 33/56] pad cipher text post error --- src/helpers/metadataUtils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 51c6e9e..54fced2 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -26,19 +26,19 @@ export async function decryptNodeData(eciesData: EciesHex, ciphertextHex: string } export async function decryptNodeDataWithPadding(eciesData: EciesHex, ciphertextHex: string, privKey: Buffer): Promise { - const ciphertextHexPadding = ciphertextHex.padStart(64, "0"); const metadata = encParamsHexToBuf(eciesData); - try { const decryptedSigBuffer = await decrypt(privKey, { ...metadata, - ciphertext: Buffer.from(ciphertextHexPadding, "hex"), + ciphertext: Buffer.from(ciphertextHex, "hex"), }); return decryptedSigBuffer; } catch (error) { + const ciphertextHexPadding = ciphertextHex.padStart(64, "0"); + log.warn("Failed to decrypt padded share cipher", error); // try without cipher text padding - return decrypt(privKey, { ...metadata, ciphertext: Buffer.from(ciphertextHex, "hex") }); + return decrypt(privKey, { ...metadata, ciphertext: Buffer.from(ciphertextHexPadding, "hex") }); } } From a52abb1f09711598528a29a408da77eb84d4ba2b Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 8 May 2024 15:31:07 +0530 Subject: [PATCH 34/56] temp --- package-lock.json | 4 +- src/helpers/nodeUtils.ts | 56 +++++++++++++++++++++------- src/interfaces.ts | 16 ++++++-- src/loglevel.ts | 2 +- src/torus.ts | 3 -- test/aqua.test.ts | 10 +++++ test/celeste.test.ts | 16 ++++++-- test/cyan.test.ts | 10 +++++ test/mainnet.test.ts | 10 +++++ test/onekey.test.ts | 15 ++++++++ test/sapphire_devnet.test.ts | 20 ++++++++++ test/sapphire_devnet_ed25519.test.ts | 6 +-- test/sapphire_mainnet.test.ts | 10 +++++ test/testnet.test.ts | 10 +++++ 14 files changed, 159 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index e0245cc..b7dd1ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "12.3.0", + "version": "13.0.0-alpha.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "12.3.0", + "version": "13.0.0-alpha.4", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.4.0", diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 0de0555..299e733 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -9,6 +9,7 @@ import { config } from "../config"; import { JRPC_METHODS } from "../constants"; import { CommitmentRequestResult, + ExtendedPublicKey, GetOrSetNonceResult, ImportedShare, ImportShareRequestResult, @@ -26,7 +27,15 @@ import { import log from "../loglevel"; import { Some } from "../some"; import { calculateMedian, getProxyCoordinatorEndpointIndex, kCombinations, normalizeKeysResult, thresholdSame } from "./common"; -import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generatePrivateKey, generateShares, keccak256 } from "./keyUtils"; +import { + derivePubKey, + generateAddressFromPrivKey, + generateAddressFromPubKey, + generatePrivateKey, + generateShares, + getSecpKeyFromEd25519, + keccak256, +} from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, decryptNodeDataWithPadding, decryptSeedData, getMetadata, getOrSetNonce } from "./metadataUtils"; @@ -128,7 +137,6 @@ export const GetPubKeyOrKeyAssign = async (params: { return result; }; - export async function retrieveOrImportShare(params: { legacyMetadataHost: string; serverTimeOffset: number; @@ -169,7 +177,6 @@ export async function retrieveOrImportShare(params: { useDkg = true, serverTimeOffset, } = params; - const minThreshold = ~~(endpoints.length / 2) + 1; await get( allowHost, { @@ -409,6 +416,7 @@ export async function retrieveOrImportShare(params: { privateKey: BN; sessionTokenData: SessionToken[]; thresholdNonceData: GetOrSetNonceResult; + thresholdPubKey: ExtendedPublicKey; nodeIndexes: BN[]; isNewKey: boolean; serverTimeOffsetResponse?: number; @@ -448,7 +456,7 @@ export async function retrieveOrImportShare(params: { return undefined; }); - const thresholdPublicKey = thresholdSame(pubkeys, minThreshold); + const thresholdPublicKey = thresholdSame(pubkeys, ~~(endpoints.length / 2) + 1); if (!thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); @@ -473,7 +481,7 @@ export async function retrieveOrImportShare(params: { ); } - const thresholdReqCount = minThreshold; + const thresholdReqCount = ~~(endpoints.length / 2) + 1; // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key @@ -564,8 +572,9 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validSigs.length < minThreshold) { - throw new Error(`Insufficient number of signatures from nodes, required: ${minThreshold}, found: ${validSigs.length}`); + const minThresholdRequired = ~~(endpoints.length / 2) + 1; + if (!verifierParams.extended_verifier_id && validSigs.length < minThresholdRequired) { + throw new Error(`Insufficient number of signatures from nodes, required: ${minThresholdRequired}, found: ${validSigs.length}`); } const validTokens = sessionTokensResolved.filter((token) => { @@ -575,8 +584,8 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validTokens.length < minThreshold) { - throw new Error(`Insufficient number of session tokens from nodes, required: ${minThreshold}, found: ${validTokens.length}`); + if (!verifierParams.extended_verifier_id && validTokens.length < minThresholdRequired) { + throw new Error(`Insufficient number of session tokens from nodes, required: ${minThresholdRequired}, found: ${validTokens.length}`); } sessionTokensResolved.forEach((x, index) => { if (!x) sessionTokenData.push(undefined); @@ -601,7 +610,7 @@ export async function retrieveOrImportShare(params: { [] as { index: BN; value: BN }[] ); // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit - const allCombis = kCombinations(decryptedShares.length, minThreshold); + const allCombis = kCombinations(decryptedShares.length, ~~(endpoints.length / 2) + 1); let privateKey: BN | null = null; for (let j = 0; j < allCombis.length; j += 1) { @@ -624,7 +633,8 @@ export async function retrieveOrImportShare(params: { if (privateKey === undefined || privateKey === null) { throw new Error("could not derive private key"); } - const thresholdIsNewKey = thresholdSame(isNewKeyResponses, minThreshold); + + const thresholdIsNewKey = thresholdSame(isNewKeyResponses, ~~(endpoints.length / 2) + 1); // Convert each string timestamp to a number const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => Number.parseInt(timestamp, 10)); @@ -634,6 +644,7 @@ export async function retrieveOrImportShare(params: { sessionTokenData, thresholdNonceData, nodeIndexes, + thresholdPubKey: thresholdPublicKey, isNewKey: thresholdIsNewKey === "true", serverTimeOffsetResponse: serverTimeOffset || calculateMedian(serverOffsetTimes), }; @@ -642,7 +653,7 @@ export async function retrieveOrImportShare(params: { }); }) .then(async (res) => { - const { privateKey, sessionTokenData, thresholdNonceData, nodeIndexes, isNewKey, serverTimeOffsetResponse } = res; + const { privateKey, sessionTokenData, thresholdNonceData, nodeIndexes, isNewKey, serverTimeOffsetResponse, thresholdPubKey } = res; let nonceResult = thresholdNonceData; if (!privateKey) throw new Error("Invalid private key returned"); const oAuthKey = privateKey; @@ -727,6 +738,7 @@ export async function retrieveOrImportShare(params: { if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); } else if (keyWithNonce && nonceResult.seed) { + console.log("keyWithNonce", keyWithNonce); // console.log("nonceResult.seed", nonceResult.seed, keyWithNonce); const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); finalPrivKey = decryptedSeed.toString("hex"); @@ -734,6 +746,19 @@ export async function retrieveOrImportShare(params: { } else { throw new Error(`Invalid keyType: ${keyType}`); } + + let postboxKey = oAuthKey; + let postboxPubX = oAuthPubkeyX; + let postboxPubY = oAuthPubkeyY; + if (keyType === "ed25519") { + const { scalar, point } = getSecpKeyFromEd25519(privateKey); + postboxKey = scalar; + postboxPubX = point.getX().toString(16, 64); + postboxPubY = point.getY().toString(16, 64); + if (thresholdPubKey.SignerX !== postboxPubX || thresholdPubKey.SignerY !== postboxPubY) { + throw new Error("Invalid postbox key"); + } + } // return reconstructed private key and ethereum address return { finalKeyData: { @@ -746,7 +771,12 @@ export async function retrieveOrImportShare(params: { walletAddress: oAuthKeyAddress, X: oAuthPubkeyX, Y: oAuthPubkeyY, - privKey: oAuthKey.toString("hex", 64).padStart(64, "0"), + privKey: oAuthKey.toString("hex", 64), + }, + postboxKeyData: { + privKey: postboxKey.toString("hex", 64), + X: postboxPubX, + Y: postboxPubY, }, sessionData: { sessionTokenData, diff --git a/src/interfaces.ts b/src/interfaces.ts index 02f6dc8..b773933 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -100,12 +100,15 @@ export type EciesHex = { [key in keyof Ecies]: string; } & { mode?: string }; +export interface ExtendedPublicKey { + X: string; + Y: string; + SignerX: string; + SignerY: string; +} export interface KeyAssignment { index: KeyIndex; - public_key: { - X: string; - Y: string; - }; + public_key: ExtendedPublicKey; threshold: string; node_index: string; // this is encrypted ciphertext @@ -180,6 +183,11 @@ export interface TorusKey { oAuthKeyData: TorusPublicKey["oAuthKeyData"] & { privKey: string; }; + postboxKeyData: { + X: string; + Y: string; + privKey: string; + }; sessionData: { sessionTokenData: SessionToken[]; sessionAuthKey: string; diff --git a/src/loglevel.ts b/src/loglevel.ts index d8d3e53..1d33267 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.enableAll(); +log.disableAll(); export default log; diff --git a/src/torus.ts b/src/torus.ts index 1730bb8..b86611f 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -144,9 +144,6 @@ class Torus { if (!shouldUseDkg && nodePubkeys.length === 0) { throw new Error("nodePubkeys param is required"); } - if (!shouldUseDkg) { - throw new Error(`useDkg param must be true for legacy network: ${this.network}`); - } return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, diff --git a/test/aqua.test.ts b/test/aqua.test.ts index de88e0e..f2e2761 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -197,6 +197,11 @@ describe("torus utils aqua", function () { Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", }, + postboxKeyData: { + X: "c7bcc239f0957bb05bda94757eb4a5f648339424b22435da5cf7a0f2b2323664", + Y: "63795690a33e575ee12d832935d563c2b5f2e1b1ffac63c32a4674152f68cb3f", + privKey: "f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d", + }, sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, @@ -238,6 +243,11 @@ describe("torus utils aqua", function () { Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", }, + postboxKeyData: { + X: "37a4ac8cbef68e88bcec5909d9b6fffb539187365bb723f3d7bffe56ae80e31d", + Y: "f963f2d08ed4dd0da9b8a8d74c6fdaeef7bdcde31f84fcce19fa2173d40b2c10", + privKey: "488d39ac548e15cfb0eaf161d86496e1645b09437df21311e24a56c4efd76355", + }, sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 25d7f13..4635908 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -12,7 +12,7 @@ const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; -describe.skip("torus utils celeste", function () { +describe("torus utils celeste", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -37,12 +37,12 @@ describe.skip("torus utils celeste", function () { oAuthKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, finalKeyData: { X: "b89b9d66b247d7294a98616b95b7bfa1675aa85a1df4d89f2780283864f1b6e9", Y: "65422a8ccd66e638899fc53497e468a9a0bf50d45c9cb85ae0ffcfc13f433ffb", - evmAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", + walletAddress: "0xC3115b9d6FaB99739b23DA9dfcBA47A4Ec4Cd113", }, metadata: { pubNonce: undefined, @@ -196,6 +196,11 @@ describe.skip("torus utils celeste", function () { Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", }, + postboxKeyData: { + X: "73b82ce0f8201a962636d404fe7a683f37c2267a9528576e1dac9964940add74", + Y: "6d28c46c5385b90322bde74d6c5096e154eae2838399f4d6e8d752f7b0c449c1", + privKey: "0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914", + }, sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, @@ -238,6 +243,11 @@ describe.skip("torus utils celeste", function () { Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", }, + postboxKeyData: { + X: "df6eb11d52e76b388a44896e9442eda17096c2b67b0be957a4ba0b68a70111ca", + Y: "bfd29ab1e97b3f7c444bb3e7ad0acb39d72589371387436c7d623d1e83f3d6eb", + privKey: "356305761eca57f27b09700d76456ad627b084152725dbfdfcfa0abcd9d4f17e", + }, sessionData: result.sessionData, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, diff --git a/test/cyan.test.ts b/test/cyan.test.ts index ece7eb0..8ff6deb 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -202,6 +202,11 @@ describe("torus utils cyan", function () { walletAddress: "0xC615aA03Dd8C9b2dc6F7c43cBDfF2c34bBa47Ec9", privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", }, + postboxKeyData: { + X: "e2ed6033951af2851d1bea98799e62fb1ff24b952c1faea17922684678ba42d1", + Y: "beef0efad88e81385952c0068ca48e8b9c2121be87cb0ddf18a68806db202359", + privKey: "5db51619684b32a2ff2375b4c03459d936179dfba401cb1c176b621e8a2e4ac8", + }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, }); @@ -244,6 +249,11 @@ describe("torus utils cyan", function () { Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", }, + postboxKeyData: { + X: "afd12f2476006ef6aa8778190b29676a70039df8688f9dee69c779bdc8ff0223", + Y: "e557a5ee879632727f5979d6b9cea69d87e3dab54a8c1b6685d86dfbfcd785dd", + privKey: "45a5b62c4ff5490baa75d33bf4f03ba6c5b0095678b0f4055312eef7b780b7bf", + }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, }); diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index af54e10..ad15987 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -201,6 +201,11 @@ describe("torus utils mainnet", function () { Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", }, + postboxKeyData: { + X: "a92d8bf1f01ad62e189a5cb0f606b89aa6df1b867128438c38e3209f3b9fc34f", + Y: "0ad1ffaecb2178b02a37c455975368be9b967ead1b281202cc8d48c77618bff1", + privKey: "0129494416ab5d5f674692b39fa49680e07d3aac01b9683ee7650e40805d4c44", + }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, }); @@ -243,6 +248,11 @@ describe("torus utils mainnet", function () { Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", }, + postboxKeyData: { + X: "52abc69ebec21deacd273dbdcb4d40066b701177bba906a187676e3292e1e236", + Y: "5e57e251db2c95c874f7ec852439302a62ef9592c8c50024e3d48018a6f77c7e", + privKey: "f55d89088a0c491d797c00da5b2ed6dc9c269c960ff121e45f255d06a91c6534", + }, metadata: { pubNonce: undefined, nonce: new BN(0), typeOfUser: "v1", upgraded: null }, nodesData: result.nodesData, }); diff --git a/test/onekey.test.ts b/test/onekey.test.ts index 25915bb..5260748 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -87,6 +87,11 @@ describe("torus onekey", function () { Y: "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a", privKey: "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", }, + postboxKeyData: { + X: "18409385c38e9729eb6b7837dc8f234256233ffab1ed7eeb1c23b230333396b4", + Y: "17d35ffc722d7a8dd88353815e9553cacf567c5f3b8d082adac9d653367ce47a", + privKey: "068ee4f97468ef1ae95d18554458d372e31968190ae38e377be59d8b3c9f7a25", + }, sessionData: { sessionTokenData: retrieveSharesResponse.sessionData.sessionTokenData, sessionAuthKey: retrieveSharesResponse.sessionData.sessionAuthKey, @@ -139,6 +144,11 @@ describe("torus onekey", function () { Y: "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27", privKey: "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a", }, + postboxKeyData: { + X: "aba2b085ae6390b3eb26802c3239bb7e3b9ed8ea6e1dcc28aeb67432571f20fc", + Y: "f1a2163cba5620b7b40241a6112e7918e9445b0b9cfbbb9d77b2de6f61ed5c27", + privKey: "d9733fc1098151f3e3289673e7c69c4ed46cbbdbc13416560e14741524d2d51a", + }, sessionData: { sessionTokenData: retrieveSharesResponse.sessionData.sessionTokenData, sessionAuthKey: retrieveSharesResponse.sessionData.sessionAuthKey, @@ -215,6 +225,11 @@ describe("torus onekey", function () { Y: "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc", privKey: "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a", }, + postboxKeyData: { + X: "49d69b8550bb0eba77595c73bf57f0463ff96adf6b50d44f9e1bcf2b3fb7976e", + Y: "d63bac65bdfc7484a28d4362347bbd098095db190c14a4ce9dbaafe74803eccc", + privKey: "f4b7e0fb1e6f6fbac539c55e22aff2900947de652d2d6254a9cd8709f505f83a", + }, sessionData: { sessionTokenData: retrieveSharesResponse.sessionData.sessionTokenData, sessionAuthKey: retrieveSharesResponse.sessionData.sessionAuthKey, diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 37cd849..01ace07 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -108,6 +108,11 @@ describe("torus utils sapphire devnet", function () { Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", }, + postboxKeyData: { + X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", + Y: "fef450a5263f7c57605dd439225faee830943cb484e8dfe1f3c82c3d538f61af", + privKey: "dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9", + }, finalKeyData: { walletAddress: "0xbeFfcC367D741C53A63F50eA805c1e93d3C64fEc", X: "2b1c47c8fbca61ee7f82a8aff53a357f6b66af0dffbef6a3e3ac649180616e51", @@ -343,6 +348,11 @@ describe("torus utils sapphire devnet", function () { Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", }, + postboxKeyData: { + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, @@ -431,6 +441,11 @@ describe("torus utils sapphire devnet", function () { Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", }, + postboxKeyData: { + X: "118a674da0c68f16a1123de9611ba655f4db1e336fe1b2d746028d65d22a3c6b", + Y: "8325432b3a3418d632b4fe93db094d6d83250eea60fe512897c0ad548737f8a5", + privKey: "6b3c872a269aa8994a5acc8cdd70ea3d8d182d42f8af421c0c39ea124e9b66fa", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, @@ -681,6 +696,11 @@ describe("torus utils sapphire devnet", function () { Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", }, + postboxKeyData: { + X: "9c591943683c0e5675f99626cea84153a3c5b72c6e7840f8b8b53d0f2bb50c67", + Y: "9d9896d82e565a2d5d437745af6e4560f3564c2ac0d0edcb72e0b508b3ac05a0", + privKey: "b47769e81328794adf3534e58d02803ca2a5e4588db81780f5bf679c77988946", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index c00ec38..5614d7d 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -19,7 +19,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe("torus utils ed25519 sapphire devnet", function () { +describe.only("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -107,8 +107,8 @@ describe("torus utils ed25519 sapphire devnet", function () { expect(result2.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); }); - it("should be able to login", async function () { - const testEmail = "edd2519TestUser@example.com"; + it.only("should be able to login", async function () { + const testEmail = "edd2519TestUser14@example.com"; const token = generateIdToken(testEmail, "ES256"); const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index 700dfb1..fb2bdee 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -265,6 +265,11 @@ describe("torus utils sapphire mainnet", function () { Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", privKey: "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478", }, + postboxKeyData: { + X: "147d0a97d498ac17172dd92546617e06f2c32c405d414dfc06632b8fbcba93d8", + Y: "cc6e57662c3866c4316c05b0fe902db9aaf5541fbf5fda854c3b4634eceeb43c", + privKey: "d768b327cbde681e5850a7d14f1c724bba2b8f8ab7fe2b1c4f1ee6979fc25478", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, @@ -312,6 +317,11 @@ describe("torus utils sapphire mainnet", function () { Y: "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391", privKey: "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906", }, + postboxKeyData: { + X: "5cd8625fc01c7f7863a58c914a8c43b2833b3d0d5059350bab4acf6f4766a33d", + Y: "198a4989615c5c2c7fa4d49c076ea7765743d09816bb998acb9ff54f5db4a391", + privKey: "90a219ac78273e82e36eaa57c15f9070195e436644319d6b9aea422bb4d31906", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey }, metadata: { pubNonce: { diff --git a/test/testnet.test.ts b/test/testnet.test.ts index 6d7c1f3..a526fdd 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -202,6 +202,11 @@ describe("torus utils migrated testnet on sapphire", function () { Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", }, + postboxKeyData: { + X: "6de2e34d488dd6a6b596524075b032a5d5eb945bcc33923ab5b88fd4fd04b5fd", + Y: "d5fb7b51b846e05362461357ec6e8ca075ea62507e2d5d7253b72b0b960927e9", + privKey: "9b0fb017db14a0a25ed51f78a258713c8ae88b5e58a43acb70b22f9e2ee138e3", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, @@ -247,6 +252,11 @@ describe("torus utils migrated testnet on sapphire", function () { Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", }, + postboxKeyData: { + X: "1c50e34ef5b7afcf5b0c6501a6ae00ec3a09a321dd885c5073dd122e2a251b95", + Y: "2cc74beb28f2c4a7c4034f80836d51b2781b36fefbeafb4eb1cd055bdf73b1e6", + privKey: "3cbfa57d702327ec1af505adc88ad577804a1a7780bc013ed9e714c547fb5cb1", + }, sessionData: { sessionTokenData: result.sessionData.sessionTokenData, sessionAuthKey: result.sessionData.sessionAuthKey, From c4a5aafbe0f3b28403d6a39e97686806770a1869 Mon Sep 17 00:00:00 2001 From: himanshu Date: Wed, 8 May 2024 17:08:06 +0530 Subject: [PATCH 35/56] error log fixes --- src/helpers/nodeUtils.ts | 5 +- src/some.ts | 7 ++- test/sapphire_devnet_ed25519.test.ts | 94 ++++++++++++++++------------ 3 files changed, 60 insertions(+), 46 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 299e733..ca0c3e5 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -458,7 +458,7 @@ export async function retrieveOrImportShare(params: { const thresholdPublicKey = thresholdSame(pubkeys, ~~(endpoints.length / 2) + 1); - if (!thresholdPublicKey) { + if (thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); } @@ -738,7 +738,6 @@ export async function retrieveOrImportShare(params: { if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); } else if (keyWithNonce && nonceResult.seed) { - console.log("keyWithNonce", keyWithNonce); // console.log("nonceResult.seed", nonceResult.seed, keyWithNonce); const decryptedSeed = await decryptSeedData(nonceResult.seed, new BN(keyWithNonce, "hex")); finalPrivKey = decryptedSeed.toString("hex"); @@ -756,7 +755,7 @@ export async function retrieveOrImportShare(params: { postboxPubX = point.getX().toString(16, 64); postboxPubY = point.getY().toString(16, 64); if (thresholdPubKey.SignerX !== postboxPubX || thresholdPubKey.SignerY !== postboxPubY) { - throw new Error("Invalid postbox key"); + // throw new Error("Invalid postbox key"); } } // return reconstructed private key and ethereum address diff --git a/src/some.ts b/src/some.ts index bb5b460..b7ca8a9 100644 --- a/src/some.ts +++ b/src/some.ts @@ -10,14 +10,17 @@ export class SomeError extends Error { predicate: string; constructor({ errors, responses, predicate }: { errors: Error[]; responses: T[]; predicate: string }) { - super("Unable to resolve enough promises."); + const message = `"Unable to resolve enough promises. ${errors.length} errors: ${errors.map((x) => x?.message || x).join(", ")} and ${ + responses.length + } predicate: ${predicate}`; + super(message); this.errors = errors; this.responses = responses; this.predicate = predicate; } get message() { - return `${super.message}. ${this.errors.length} errors: ${this.errors.map((x) => x.message || x).join(", ")} and ${ + return `${super.message}. ${this.errors.length} errors: ${this.errors.map((x) => x?.message || x).join(", ")} and ${ this.responses.length } responses: ${JSON.stringify(this.responses)}`; } diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 5614d7d..ce9fa0f 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -108,50 +108,62 @@ describe.only("torus utils ed25519 sapphire devnet", function () { }); it.only("should be able to login", async function () { - const testEmail = "edd2519TestUser14@example.com"; - const token = generateIdToken(testEmail, "ES256"); + const testEmail = "edd2519TestUser95@example.com"; + // const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }; + const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); + // await torus.getPublicAddress(nodeDetails.torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); + const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: testEmail }, - token, - nodeDetails.torusNodePub - ); + // torusNodeEndpoints[0] = "example.com"; + // torusNodeEndpoints[1] = "example.com"; - delete result.metadata.serverTimeOffset; - delete result.sessionData; - expect(result).eql({ - oAuthKeyData: { - walletAddress: "7yZNbrFdLgE1ck8BQvDfNpVsgU5BYXotEoXiasTwdWWr", - X: "7a5d7618aa6abff0a27fd273cd38ef2f81c19a67c488f65d2587b2d7a744dd70", - Y: "179de2aa479958f2a744b6a8810a38e27257679d09f183f9aa5b2ff81f40a367", - privKey: "0325b66f131f040fbd23f8feb9633f10440986c5413063f6dd3f23166503b5ea", - }, - finalKeyData: { - walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", - X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", - Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", - privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f783", - }, - metadata: { - pubNonce: { - X: "4533a0c1907b12187ab41bceaefee8d62b2709d66b67b51a6f39925bfb543933", - Y: "6862380e59f04a6bbdb3515ee386af44961b403cc61c7cb9725d2e60d250b82", - }, - nonce: new BN("da32347189e4a992a9367cb8970d741fff3febccd9d92bb5ac247d97dc5c510", "hex"), - typeOfUser: "v2", - upgraded: false, - }, - nodesData: result.nodesData, - }); - const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { - verifier: TORUS_TEST_VERIFIER, - verifierId: testEmail, - }); - expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); + for (let i = 0; i < 1; i++) { + const testEmail1 = `edd2519TestUser951121saaaa${i}@example.com`; + const token = generateIdToken(`${testEmail1}`, "ES256"); + + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: testEmail1 }, + token, + nodeDetails.torusNodePub + ); + console.log("result", result.finalKeyData.privKey); + } + + // delete result.metadata.serverTimeOffset; + // delete result.sessionData; + // expect(result).eql({ + // oAuthKeyData: { + // walletAddress: "7yZNbrFdLgE1ck8BQvDfNpVsgU5BYXotEoXiasTwdWWr", + // X: "7a5d7618aa6abff0a27fd273cd38ef2f81c19a67c488f65d2587b2d7a744dd70", + // Y: "179de2aa479958f2a744b6a8810a38e27257679d09f183f9aa5b2ff81f40a367", + // privKey: "0325b66f131f040fbd23f8feb9633f10440986c5413063f6dd3f23166503b5ea", + // }, + // finalKeyData: { + // walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", + // X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", + // Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", + // privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f783", + // }, + // metadata: { + // pubNonce: { + // X: "4533a0c1907b12187ab41bceaefee8d62b2709d66b67b51a6f39925bfb543933", + // Y: "6862380e59f04a6bbdb3515ee386af44961b403cc61c7cb9725d2e60d250b82", + // }, + // nonce: new BN("da32347189e4a992a9367cb8970d741fff3febccd9d92bb5ac247d97dc5c510", "hex"), + // typeOfUser: "v2", + // upgraded: false, + // }, + // nodesData: result.nodesData, + // }); + // const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + // verifier: TORUS_TEST_VERIFIER, + // verifierId: testEmail, + // }); + // expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); }); it("should be able to key assign", async function () { From 9cca752b39dfdd304f4f4077c0330b446374eb7b Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 9 May 2024 13:12:14 +0530 Subject: [PATCH 36/56] better error msgs --- src/helpers/keyUtils.ts | 20 ++++++++++++++++++-- src/helpers/metadataUtils.ts | 6 +++++- src/helpers/nodeUtils.ts | 26 ++++++++++++++++++++------ src/loglevel.ts | 2 +- src/some.ts | 7 ++++--- test/sapphire_devnet_ed25519.test.ts | 6 +++--- 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index a08c04f..49e4f85 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -88,8 +88,22 @@ export const getSecpKeyFromEd25519 = ( } => { const ed25519Key = ed25519Scalar.toString("hex", 64); const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); - const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n); - const secpKeyPair = secp256k1Curve.keyFromPrivate(secpKey.toString("hex", 64)); + const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n).toString("hex", 64); + const bufferKey = Buffer.from(secpKey, "hex"); + + const secpKeyPair = secp256k1Curve.keyFromPrivate(bufferKey); + + if (bufferKey.length < 32) { + console.log( + "secpKey.toArrayLike(Buffer)", + ed25519Key, + secpKey, + keyHash.length, + bufferKey.length, + secpKeyPair.getPrivate().toArrayLike(Buffer).length + ); + throw new Error("Invalid key length, please try again"); + } return { scalar: secpKeyPair.getPrivate(), point: secpKeyPair.getPublic(), @@ -118,6 +132,8 @@ export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise { const decryptionKey = getSecpKeyFromEd25519(finalUserKey); const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; + console.log("final decryption key", decryptionKey.scalar.toString("hex", 64)); const bufferMetadata = { ephemPublicKey: Buffer.from(seedJson.metadata.ephemPublicKey, "hex"), iv: Buffer.from(seedJson.metadata.iv, "hex"), mac: Buffer.from(seedJson.metadata.mac, "hex"), mode: "AES256", }; - const decText = await decrypt(decryptionKey.scalar.toArrayLike(Buffer), { + const bufferKey = Buffer.from(decryptionKey.scalar.toString("hex", 64), "hex"); + console.log("key len", bufferKey.length); + + const decText = await decrypt(bufferKey, { ...bufferMetadata, ciphertext: Buffer.from(seedJson.enc_text, "hex"), }); diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index ca0c3e5..1ebfc5a 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -314,7 +314,7 @@ export async function retrieveOrImportShare(params: { } } - return Promise.reject(new Error(`invalid ${JSON.stringify(resultArr)}`)); + return Promise.reject(new Error(`invalid commitment results, ${JSON.stringify(resultArr)}`)); }) .then((responses) => { const promiseArrRequest: Promise | JRPCResponse>[] = []; @@ -458,7 +458,7 @@ export async function retrieveOrImportShare(params: { const thresholdPublicKey = thresholdSame(pubkeys, ~~(endpoints.length / 2) + 1); - if (thresholdPublicKey) { + if (!thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); } @@ -588,7 +588,7 @@ export async function retrieveOrImportShare(params: { throw new Error(`Insufficient number of session tokens from nodes, required: ${minThresholdRequired}, found: ${validTokens.length}`); } sessionTokensResolved.forEach((x, index) => { - if (!x) sessionTokenData.push(undefined); + if (!x || !sessionSigsResolved[index]) sessionTokenData.push(undefined); else sessionTokenData.push({ token: x.toString("base64"), @@ -649,7 +649,12 @@ export async function retrieveOrImportShare(params: { serverTimeOffsetResponse: serverTimeOffset || calculateMedian(serverOffsetTimes), }; } - throw new Error("Invalid"); + if (completedRequests.length < thresholdReqCount) { + throw new Error(`Waiting for results from more nodes, pending: ${thresholdReqCount - completedRequests.length}`); + } + throw new Error( + `Invalid results, threshold pub key: ${thresholdPublicKey}, nonce data found: ${!!thresholdNonceData}, extended verifierId: ${verifierParams.extended_verifier_id}` + ); }); }) .then(async (res) => { @@ -731,6 +736,7 @@ export async function retrieveOrImportShare(params: { if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); keyWithNonce = privateKeyWithNonce.toString("hex", 64); + console.log("keyWithNonce", keyWithNonce); } if (keyType === "secp256k1") { finalPrivKey = keyWithNonce; @@ -754,8 +760,16 @@ export async function retrieveOrImportShare(params: { postboxKey = scalar; postboxPubX = point.getX().toString(16, 64); postboxPubY = point.getY().toString(16, 64); - if (thresholdPubKey.SignerX !== postboxPubX || thresholdPubKey.SignerY !== postboxPubY) { - // throw new Error("Invalid postbox key"); + if (thresholdPubKey.SignerX.padStart(64, "0") !== postboxPubX || thresholdPubKey.SignerY.padStart(64, "0") !== postboxPubY) { + console.log( + "thresholdPubKey.SignerX", + thresholdPubKey.SignerX, + postboxPubX, + thresholdPubKey.SignerY, + postboxPubY, + postboxKey.toString("hex", 64) + ); + throw new Error("Invalid postbox key"); } } // return reconstructed private key and ethereum address diff --git a/src/loglevel.ts b/src/loglevel.ts index 1d33267..d8d3e53 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.disableAll(); +log.enableAll(); export default log; diff --git a/src/some.ts b/src/some.ts index b7ca8a9..4bc8328 100644 --- a/src/some.ts +++ b/src/some.ts @@ -10,9 +10,10 @@ export class SomeError extends Error { predicate: string; constructor({ errors, responses, predicate }: { errors: Error[]; responses: T[]; predicate: string }) { - const message = `"Unable to resolve enough promises. ${errors.length} errors: ${errors.map((x) => x?.message || x).join(", ")} and ${ - responses.length - } predicate: ${predicate}`; + const message = `Unable to resolve enough promises. + errors: ${errors.map((x) => x?.message || x).join(", ")}, + ${responses.length} responses, + predicate error: ${predicate}`; super(message); this.errors = errors; this.responses = responses; diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index ce9fa0f..4125cc5 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -118,10 +118,10 @@ describe.only("torus utils ed25519 sapphire devnet", function () { // torusNodeEndpoints[0] = "example.com"; // torusNodeEndpoints[1] = "example.com"; - for (let i = 0; i < 1; i++) { - const testEmail1 = `edd2519TestUser951121saaaa${i}@example.com`; + for (let i = 0; i < 1000; i++) { + const testEmail1 = `edd2519TestUser951aaaa1a2q1saaaaaaa2@example.com${i}`; const token = generateIdToken(`${testEmail1}`, "ES256"); - + console.log("testEmail1", testEmail1); const result = await torus.retrieveShares( torusNodeEndpoints, nodeDetails.torusIndexes, From 49094e476de73f3e1c5670e758af21f50f3ee509 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 9 May 2024 15:36:55 +0530 Subject: [PATCH 37/56] return postbox key data obj --- src/helpers/keyUtils.ts | 10 --- src/helpers/metadataUtils.ts | 3 - src/helpers/nodeUtils.ts | 9 --- test/sapphire_devnet_ed25519.test.ts | 108 +++++++++++++-------------- 4 files changed, 54 insertions(+), 76 deletions(-) diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 49e4f85..908f28f 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -94,14 +94,6 @@ export const getSecpKeyFromEd25519 = ( const secpKeyPair = secp256k1Curve.keyFromPrivate(bufferKey); if (bufferKey.length < 32) { - console.log( - "secpKey.toArrayLike(Buffer)", - ed25519Key, - secpKey, - keyHash.length, - bufferKey.length, - secpKeyPair.getPrivate().toArrayLike(Buffer).length - ); throw new Error("Invalid key length, please try again"); } return { @@ -132,8 +124,6 @@ export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise { const decryptionKey = getSecpKeyFromEd25519(finalUserKey); const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; - console.log("final decryption key", decryptionKey.scalar.toString("hex", 64)); const bufferMetadata = { ephemPublicKey: Buffer.from(seedJson.metadata.ephemPublicKey, "hex"), iv: Buffer.from(seedJson.metadata.iv, "hex"), @@ -185,8 +184,6 @@ export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { mode: "AES256", }; const bufferKey = Buffer.from(decryptionKey.scalar.toString("hex", 64), "hex"); - console.log("key len", bufferKey.length); - const decText = await decrypt(bufferKey, { ...bufferMetadata, ciphertext: Buffer.from(seedJson.enc_text, "hex"), diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 1ebfc5a..94972a6 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -736,7 +736,6 @@ export async function retrieveOrImportShare(params: { if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); keyWithNonce = privateKeyWithNonce.toString("hex", 64); - console.log("keyWithNonce", keyWithNonce); } if (keyType === "secp256k1") { finalPrivKey = keyWithNonce; @@ -761,14 +760,6 @@ export async function retrieveOrImportShare(params: { postboxPubX = point.getX().toString(16, 64); postboxPubY = point.getY().toString(16, 64); if (thresholdPubKey.SignerX.padStart(64, "0") !== postboxPubX || thresholdPubKey.SignerY.padStart(64, "0") !== postboxPubY) { - console.log( - "thresholdPubKey.SignerX", - thresholdPubKey.SignerX, - postboxPubX, - thresholdPubKey.SignerY, - postboxPubY, - postboxKey.toString("hex", 64) - ); throw new Error("Invalid postbox key"); } } diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 4125cc5..e008174 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -19,7 +19,7 @@ const TORUS_TEST_VERIFIER = "torus-test-health"; const TORUS_TEST_AGGREGATE_VERIFIER = "torus-test-health-aggregate"; const HashEnabledVerifier = "torus-test-verifierid-hash"; -describe.only("torus utils ed25519 sapphire devnet", function () { +describe("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; let TORUS_NODE_MANAGER: NodeManager; @@ -107,63 +107,58 @@ describe.only("torus utils ed25519 sapphire devnet", function () { expect(result2.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); }); - it.only("should be able to login", async function () { - const testEmail = "edd2519TestUser95@example.com"; - // const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }; - + it("should be able to login", async function () { + const testEmail = "edd2519TestUser951@example.com"; const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: testEmail }); - // await torus.getPublicAddress(nodeDetails.torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; - // torusNodeEndpoints[0] = "example.com"; - // torusNodeEndpoints[1] = "example.com"; - - for (let i = 0; i < 1000; i++) { - const testEmail1 = `edd2519TestUser951aaaa1a2q1saaaaaaa2@example.com${i}`; - const token = generateIdToken(`${testEmail1}`, "ES256"); - console.log("testEmail1", testEmail1); - const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: testEmail1 }, - token, - nodeDetails.torusNodePub - ); - console.log("result", result.finalKeyData.privKey); - } - // delete result.metadata.serverTimeOffset; - // delete result.sessionData; - // expect(result).eql({ - // oAuthKeyData: { - // walletAddress: "7yZNbrFdLgE1ck8BQvDfNpVsgU5BYXotEoXiasTwdWWr", - // X: "7a5d7618aa6abff0a27fd273cd38ef2f81c19a67c488f65d2587b2d7a744dd70", - // Y: "179de2aa479958f2a744b6a8810a38e27257679d09f183f9aa5b2ff81f40a367", - // privKey: "0325b66f131f040fbd23f8feb9633f10440986c5413063f6dd3f23166503b5ea", - // }, - // finalKeyData: { - // walletAddress: "7iBcf5du7C7pCocbvoXHDbNXnzF9hSTNRuRiqfGC56Th", - // X: "738dfd57d80945defc6d3bc4deeeffbcecf344a4186b1e756eae54c5f60a4b63", - // Y: "7082c093c550e1069935a6f7f639901c84e14e4030a8561cba4b8ccfd7efb263", - // privKey: "082d9495b9147bac19699ae3109606cbaeea1bf65772b6d7e652ebf77f67f783", - // }, - // metadata: { - // pubNonce: { - // X: "4533a0c1907b12187ab41bceaefee8d62b2709d66b67b51a6f39925bfb543933", - // Y: "6862380e59f04a6bbdb3515ee386af44961b403cc61c7cb9725d2e60d250b82", - // }, - // nonce: new BN("da32347189e4a992a9367cb8970d741fff3febccd9d92bb5ac247d97dc5c510", "hex"), - // typeOfUser: "v2", - // upgraded: false, - // }, - // nodesData: result.nodesData, - // }); - // const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { - // verifier: TORUS_TEST_VERIFIER, - // verifierId: testEmail, - // }); - // expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); + const token = generateIdToken(`${testEmail}`, "ES256"); + const result = await torus.retrieveShares( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: testEmail }, + token, + nodeDetails.torusNodePub + ); + + delete result.metadata.serverTimeOffset; + delete result.sessionData; + expect(result).eql({ + oAuthKeyData: { + walletAddress: "HV19ETHePfCtZK55Bo5znHXLfd46nu4AQbjtbYumY7ea", + X: "1f5f95f5af0a67b4af731608fdb26115efcb011dcf64a355bf2442e4ec058ae0", + Y: "33f3317a574a5444b78aecc56dd894a56d1fbb90134bc7c63d0f9d11f969e7f4", + privKey: "07b1ff9ec97c93ac3d5125db8283ec0b22056623d0a9407a48c9def302db07b7", + }, + postboxKeyData: { + X: "a7fa19a07eb387e3b1a95843f7d56f8ca88d11c632c4f53b8554068876451d27", + Y: "6ddc5c79c28d197991ecf9304b4e66ecc2e98dcf3cb73ec3c79953bd87e4a6ff", + privKey: "fa5efb87dbdcea273654342d622fcbfa087f4a572caf76d2214e00a8732c6ddf", + }, + finalKeyData: { + walletAddress: "Dp6eiDQs7LbHLVATSEaA7NUm9DkEAZTXdzXy13vbYoq8", + X: "2cfc2713bd866494690b50d0cb1500878903130a0a1a31fae1ffa5f8cd436407", + Y: "775cc21e123af488ad2c1fd70b22f9427a0596691c991186d42e69fa08ee5cbe", + privKey: "cfe3a737880b01da41765e90466400512564bf3e12648e8e715ae54b53b1e11b", + }, + metadata: { + pubNonce: { + X: "78f007266e249301a241bcb72dba7d305f41f11a432dd8f4dec22c9a0035b3ac", + Y: "7e0545c176528910726ad528e12e1fa39e106ad06957e807a2660c9214596d33", + }, + nonce: new BN("58c39dd2c8dcdbd740b758623c88b9dfb36d6e3b590d073a1456c0268af8270", "hex"), + typeOfUser: "v2", + upgraded: false, + }, + nodesData: result.nodesData, + }); + const result2 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { + verifier: TORUS_TEST_VERIFIER, + verifierId: testEmail, + }); + expect(result2.finalKeyData.walletAddress).eql(result.finalKeyData.walletAddress); }); it("should be able to key assign", async function () { @@ -367,6 +362,11 @@ describe.only("torus utils ed25519 sapphire devnet", function () { Y: "44af643f9200d11c5f60212de9470f92806df18eeea730a8736e4570611761f2", privKey: "47c471c6c3b53f751e39feae967359b9258a790a30f2db394625f76b0c84ada0", }, + postboxKeyData: { + X: "8a25dd3b35a77927e5f094b333ccd69a77acec89868db646e2afbf363f191b11", + Y: "aa9282b02c5af9d06d206631ac503c218f807f0365c0a8677f6347fd01f8ffb0", + privKey: "239c7b52e39074d8c580e3fcd2950dbd2562e8b54340d2628bac055546b6a97e", + }, oAuthKeyData: { walletAddress: "DybMLmBwiPqt8GXpDW2MwHi5ZqEtrbgxgwcf7shPdTWg", X: "45c531429896ab89078789018b21639dab308b7d3952d9df243177e60fc0eb1f", From 99b7a773b003cf94f5e16fe5f33345cf6bcfbd1a Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 9 May 2024 15:42:23 +0530 Subject: [PATCH 38/56] Release 13.0.0-alpha.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7dd1ef..1511951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.4", + "version": "13.0.0-alpha.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.4", + "version": "13.0.0-alpha.5", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.4.0", diff --git a/package.json b/package.json index e8b486a..313dbd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.4", + "version": "13.0.0-alpha.5", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 68d1bd24cb611cdeb450e3c607b9d9e2e02c5e4e Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 14 May 2024 14:11:23 +0530 Subject: [PATCH 39/56] update function to return correct postbox key --- src/torus.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/torus.ts b/src/torus.ts index b86611f..ad48690 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -105,9 +105,9 @@ class Torus { static getPostboxKey(torusKey: TorusKey): string { if (torusKey.metadata.typeOfUser === "v1") { - return torusKey.finalKeyData.privKey || torusKey.oAuthKeyData.privKey; + return torusKey.finalKeyData.privKey || torusKey.postboxKeyData.privKey; } - return torusKey.oAuthKeyData.privKey; + return torusKey.postboxKeyData.privKey; } async retrieveShares( From 8f930ea0f4a2a407a4b97016d364737c4db4fcc3 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 14 May 2024 14:14:08 +0530 Subject: [PATCH 40/56] fix metadata msg expiry test case --- test/testnet.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testnet.test.ts b/test/testnet.test.ts index a526fdd..cbaf095 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -276,7 +276,7 @@ describe("torus utils migrated testnet on sapphire", function () { network: TORUS_LEGACY_NETWORK.TESTNET, clientId: "YOUR_CLIENT_ID", enableOneKey: true, - serverTimeOffset: -100, + serverTimeOffset: -700, }); const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); try { From 11a438419b7967ac80abf93855ce898cf1d5d86c Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 16 May 2024 09:39:14 +0530 Subject: [PATCH 41/56] Release 13.0.0-alpha.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1511951..ad16ca8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.5", + "version": "13.0.0-alpha.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.5", + "version": "13.0.0-alpha.6", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.4.0", diff --git a/package.json b/package.json index 313dbd0..49de703 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.5", + "version": "13.0.0-alpha.6", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 9c8d4c6c4646f8316e1614aad557e1df4ff31f13 Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 31 May 2024 11:16:13 +0530 Subject: [PATCH 42/56] add sapphire mainnet support for ed25519 --- src/torus.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/torus.ts b/src/torus.ts index ad48690..db8d9b6 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -1,12 +1,4 @@ -import { - INodePub, - LEGACY_NETWORKS_ROUTE_MAP, - METADATA_MAP, - SIGNER_MAP, - TORUS_LEGACY_NETWORK_TYPE, - TORUS_NETWORK_TYPE, - TORUS_SAPPHIRE_NETWORK, -} from "@toruslabs/constants"; +import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, METADATA_MAP, SIGNER_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; @@ -67,7 +59,7 @@ class Torus { }: TorusCtorOptions) { if (!clientId) throw new Error("Please provide a valid clientId in constructor"); if (!network) throw new Error("Please provide a valid network in constructor"); - if (keyType === "ed25519" && network !== TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET) { + if (keyType === "ed25519" && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { throw new Error(`keyType: ${keyType} is not supported by ${network} network`); } this.keyType = keyType; From 6c7e323f7389557b81a5944450bada30e4daa230 Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 31 May 2024 11:17:18 +0530 Subject: [PATCH 43/56] disable logging --- src/loglevel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loglevel.ts b/src/loglevel.ts index d8d3e53..1d33267 100644 --- a/src/loglevel.ts +++ b/src/loglevel.ts @@ -1,6 +1,6 @@ import loglevel from "loglevel"; const log = loglevel.getLogger("torus.js"); -log.enableAll(); +log.disableAll(); export default log; From 30cf1d9501e57f2053cb7526bad2a5813e1e95aa Mon Sep 17 00:00:00 2001 From: himanshu Date: Fri, 31 May 2024 11:24:01 +0530 Subject: [PATCH 44/56] Release 13.0.0-alpha.7 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad16ca8..00a398c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.6", + "version": "13.0.0-alpha.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.6", + "version": "13.0.0-alpha.7", "license": "MIT", "dependencies": { "@toruslabs/constants": "^13.4.0", diff --git a/package.json b/package.json index 49de703..45e0ae5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "13.0.0-alpha.6", + "version": "13.0.0-alpha.7", "description": "Handle communication with torus nodes", "main": "dist/torusUtils.cjs.js", "module": "dist/torusUtils.esm.js", From 2b394126b2d315d0daa16fbaf8dc60ab8c2de5bb Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 18 Jun 2024 18:25:19 +0530 Subject: [PATCH 45/56] enable mainnet import test --- test/sapphire_mainnet.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index fb2bdee..22cb29c 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -61,7 +61,7 @@ describe("torus utils sapphire mainnet", function () { }); }); - it.skip("should be able to import a key for a new user", async function () { + it("should be able to import a key for a new user", async function () { const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); const ec = new EC("secp256k1"); From 7d0f687d56aa741bece37b50c8c293d367c0ed9e Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 11 Jul 2024 08:51:52 +0530 Subject: [PATCH 46/56] fix http calls --- src/helpers/nodeUtils.ts | 3 +-- test/helpers.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 8d2d415..654c853 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -384,7 +384,6 @@ export async function retrieveOrImportShare(params: { } const p = post>( endpoints[proxyEndpointNum], - generateJsonRPCObject(JRPC_METHODS.IMPORT_SHARES, { encrypted: "yes", use_temp: true, @@ -392,7 +391,7 @@ export async function retrieveOrImportShare(params: { key_type: keyType, one_key_flow: true, }), - null, + {}, { logTracingHeader: config.logRequestTracing } ).catch((err) => log.error("share req", err)); promiseArrRequest.push(p); diff --git a/test/helpers.ts b/test/helpers.ts index 294501d..b796d38 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -38,7 +38,7 @@ export const lookupVerifier = (endpoint: string, pubKeyX: string, pubKeyY: strin pub_key_x: pubKeyX, pub_key_y: pubKeyY, }), - null, + {}, { logTracingHeader: config.logRequestTracing } ); }; From abdd7a54e842f23029bafb5684c703ed7fa09aa3 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 11 Jul 2024 12:39:21 +0530 Subject: [PATCH 47/56] use constants for curves --- src/helpers/common.ts | 13 +++++-------- src/helpers/keyUtils.ts | 29 ++++++++++++++++++++--------- src/helpers/metadataUtils.ts | 10 +++++----- src/helpers/nodeUtils.ts | 10 +++++----- src/torus.ts | 24 ++++++++++++++++-------- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/helpers/common.ts b/src/helpers/common.ts index ec2a333..1ecb58c 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -1,4 +1,4 @@ -import { JRPCResponse } from "@toruslabs/constants"; +import { JRPCResponse, KEY_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import { BN } from "bn.js"; import { ec as EC } from "elliptic"; @@ -7,14 +7,11 @@ import JsonStringify from "json-stable-stringify"; import { CommitmentRequestResult, EciesHex, KeyType, VerifierLookupResponse } from "../interfaces"; import { keccak256 } from "./keyUtils"; -export const ed25519Curve = new EC("ed25519"); -export const secp256k1Curve = new EC("secp256k1"); - export const getKeyCurve = (keyType: KeyType) => { - if (keyType === "ed25519") { - return ed25519Curve; - } else if (keyType === "secp256k1") { - return secp256k1Curve; + if (keyType === KEY_TYPE.ED25519) { + return new EC(KEY_TYPE.ED25519); + } else if (keyType === KEY_TYPE.SECP256K1) { + return new EC(KEY_TYPE.SECP256K1); } throw new Error(`Invalid keyType: ${keyType}`); }; diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index 908f28f..e506bec 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -1,4 +1,4 @@ -import { INodePub } from "@toruslabs/constants"; +import { INodePub, KEY_TYPE } from "@toruslabs/constants"; import { Ecies, encrypt } from "@toruslabs/eccrypto"; import BN from "bn.js"; import base58 from "bs58"; @@ -9,7 +9,7 @@ import stringify from "json-stable-stringify"; import log from "loglevel"; import { EncryptedSeed, ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; -import { ed25519Curve, encParamsBufToHex, getKeyCurve, secp256k1Curve } from "./common"; +import { encParamsBufToHex, getKeyCurve } from "./common"; import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; import { generateNonceMetadataParams } from "./metadataUtils"; @@ -60,6 +60,7 @@ export function getEd25519ExtendedPublicKey(keyBuffer: Buffer): { scalar: BN; point: curve.base.BasePoint; } { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); const len = 32; const G = ed25519Curve.g; const N = ed25519Curve.n; @@ -86,6 +87,8 @@ export const getSecpKeyFromEd25519 = ( scalar: BN; point: curve.base.BasePoint; } => { + const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); + const ed25519Key = ed25519Scalar.toString("hex", 64); const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n).toString("hex", 64); @@ -103,6 +106,8 @@ export const getSecpKeyFromEd25519 = ( }; export function encodeEd25519Point(point: curve.base.BasePoint) { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); + const encodingLength = Math.ceil(ed25519Curve.n.bitLength() / 8); const enc = point.getY().toArrayLike(Buffer, "le", encodingLength); enc[encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0; @@ -110,6 +115,8 @@ export function encodeEd25519Point(point: curve.base.BasePoint) { } export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise => { + const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); + const finalEd25519Key = getEd25519ExtendedPublicKey(ed25519Seed); const encryptionKey = getSecpKeyFromEd25519(finalEd25519Key.scalar); const encryptedSeed = await encrypt(Buffer.from(encryptionKey.point.encodeCompressed("hex"), "hex"), ed25519Seed); @@ -138,6 +145,8 @@ export const generateEd25519KeyData = async (ed25519Seed: Buffer): Promise => { + const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); + const scalar = new BN(scalarBuffer); const randomNonce = new BN(generatePrivateKey(secp256k1Curve, Buffer)); const oAuthKey = scalar.sub(randomNonce).umod(secp256k1Curve.curve.n); @@ -162,11 +171,11 @@ export const generateSecp256k1KeyData = async (scalarBuffer: Buffer): Promise { + return new EC("secp256k1"); +}; export const generateShares = async ( ecCurve: EC, @@ -210,7 +221,7 @@ export const generateShares = async ( nodePubkeys: INodePub[], privKey: Buffer ) => { - const keyData = keyType === "ed25519" ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); + const keyData = keyType === KEY_TYPE.ED25519 ? await generateEd25519KeyData(privKey) : await generateSecp256k1KeyData(privKey); const { metadataNonce, oAuthKeyScalar: oAuthKey, encryptedSeed, metadataSigningKey } = keyData; const threshold = ~~(nodePubkeys.length / 2) + 1; const degree = threshold - 1; @@ -231,7 +242,7 @@ export const generateShares = async ( if (!nodePubkeys[i]) { throw new Error(`Missing node pub key for node index: ${nodeIndexesBn[i].toString("hex", 64)}`); } - const nodePubKey = encryptionEC.keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); + const nodePubKey = getEncryptionEC().keyFromPublic({ x: nodePubkeys[i].X, y: nodePubkeys[i].Y }); encPromises.push( encrypt(Buffer.from(nodePubKey.getPublic().encodeCompressed("hex"), "hex"), Buffer.from(shareJson.share.padStart(64, "0"), "hex")) ); diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 6998d3c..2e959fd 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -1,4 +1,4 @@ -import { LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; +import { KEY_TYPE, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE, TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; import { decrypt } from "@toruslabs/eccrypto"; import { Data, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; @@ -17,7 +17,7 @@ import { SapphireMetadataParams, SetNonceData, } from "../interfaces"; -import { encParamsHexToBuf, secp256k1Curve } from "./common"; +import { encParamsHexToBuf, getKeyCurve } from "./common"; import { getSecpKeyFromEd25519, keccak256 } from "./keyUtils"; export function convertMetadataToNonce(params: { message?: string }) { if (!params || !params.message) { @@ -93,7 +93,7 @@ export function generateNonceMetadataParams( seed?: string ): NonceMetadataParams { // metadata only uses secp for sig validation - const key = secp256k1Curve.keyFromPrivate(privateKey.toString("hex", 64)); + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privateKey.toString("hex", 64)); const setData: Partial = { operation, timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), @@ -157,7 +157,7 @@ export async function getOrSetNonce( if (nonce.cmp(new BN(0)) === 0) { throw new Error("nonce is required while `getOrSetNonce` for non legacy metadata"); } - if (keyType === "ed25519" && !seed) { + if (keyType === KEY_TYPE.ED25519 && !seed) { throw new Error("seed is required while `getOrSetNonce` for non legacy metadata for ed25519 key type"); } const data = generateNonceMetadataParams(serverTimeOffset, operation, privKey, keyType, nonce, seed); @@ -218,7 +218,7 @@ export async function getOrSetSapphireMetadataNonce( set_data: { operation: "getOrSetNonce" }, }; if (privKey) { - const key = secp256k1Curve.keyFromPrivate(privKey.toString("hex", 64)); + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privKey.toString("hex", 64)); const setData = { operation: "getOrSetNonce", diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 654c853..b194b48 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -1,4 +1,4 @@ -import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import { INodePub, KEY_TYPE, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { generatePrivate, getPublic } from "@toruslabs/eccrypto"; import { generateJsonRPCObject, get, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; @@ -224,7 +224,7 @@ export async function retrieveOrImportShare(params: { } finalImportedShares = newImportedShares; } else if (!useDkg) { - const bufferKey = keyType === "secp256k1" ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); + const bufferKey = keyType === KEY_TYPE.SECP256K1 ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, Buffer.from(bufferKey)); finalImportedShares = [...finalImportedShares, ...generatedShares]; } @@ -757,9 +757,9 @@ export async function retrieveOrImportShare(params: { const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); keyWithNonce = privateKeyWithNonce.toString("hex", 64); } - if (keyType === "secp256k1") { + if (keyType === KEY_TYPE.SECP256K1) { finalPrivKey = keyWithNonce; - } else if (keyType === "ed25519") { + } else if (keyType === KEY_TYPE.ED25519) { if (keyWithNonce && !nonceResult.seed) { throw new Error("Invalid data, seed data is missing for ed25519 key, Please report this bug"); } else if (keyWithNonce && nonceResult.seed) { @@ -774,7 +774,7 @@ export async function retrieveOrImportShare(params: { let postboxKey = oAuthKey; let postboxPubX = oAuthPubkeyX; let postboxPubY = oAuthPubkeyY; - if (keyType === "ed25519") { + if (keyType === KEY_TYPE.ED25519) { const { scalar, point } = getSecpKeyFromEd25519(privateKey); postboxKey = scalar; postboxPubX = point.getX().toString(16, 64); diff --git a/src/torus.ts b/src/torus.ts index db8d9b6..54adecb 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -1,4 +1,12 @@ -import { INodePub, LEGACY_NETWORKS_ROUTE_MAP, METADATA_MAP, SIGNER_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import { + INodePub, + KEY_TYPE, + LEGACY_NETWORKS_ROUTE_MAP, + METADATA_MAP, + SIGNER_MAP, + TORUS_LEGACY_NETWORK_TYPE, + TORUS_NETWORK_TYPE, +} from "@toruslabs/constants"; import { setAPIKey, setEmbedHost } from "@toruslabs/http-helpers"; import BN from "bn.js"; import { curve, ec as EC } from "elliptic"; @@ -46,7 +54,7 @@ class Torus { private legacyMetadataHost: string; - private keyType: KeyType = "secp256k1"; + private keyType: KeyType = KEY_TYPE.SECP256K1; constructor({ enableOneKey = false, @@ -55,11 +63,11 @@ class Torus { serverTimeOffset = 0, allowHost, legacyMetadataHost, - keyType = "secp256k1", + keyType = KEY_TYPE.SECP256K1, }: TorusCtorOptions) { if (!clientId) throw new Error("Please provide a valid clientId in constructor"); if (!network) throw new Error("Please provide a valid network in constructor"); - if (keyType === "ed25519" && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { + if (keyType === KEY_TYPE.ED25519 && LEGACY_NETWORKS_ROUTE_MAP[network as TORUS_LEGACY_NETWORK_TYPE]) { throw new Error(`keyType: ${keyType} is not supported by ${network} network`); } this.keyType = keyType; @@ -128,7 +136,7 @@ class Torus { let shouldUseDkg; if (typeof useDkg === "boolean") { shouldUseDkg = useDkg; - } else if (this.keyType === "ed25519") { + } else if (this.keyType === KEY_TYPE.ED25519) { shouldUseDkg = false; } else { shouldUseDkg = true; @@ -186,13 +194,13 @@ class Torus { let privKeyBuffer; - if (this.keyType === "secp256k1") { + if (this.keyType === KEY_TYPE.SECP256K1) { privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); if (privKeyBuffer.length !== 32) { throw new Error("Invalid private key length for given secp256k1 key"); } } - if (this.keyType === "ed25519") { + if (this.keyType === KEY_TYPE.ED25519) { privKeyBuffer = Buffer.from(newPrivateKey, "hex"); if (privKeyBuffer.length !== 32) { throw new Error("Invalid private key length for given ed25519 key"); @@ -200,7 +208,7 @@ class Torus { } const sharesData = await generateShares(this.ec, this.keyType, this.serverTimeOffset, nodeIndexes, nodePubkeys, privKeyBuffer); - if (this.keyType === "ed25519") { + if (this.keyType === KEY_TYPE.ED25519) { const ed25519Key = getEd25519ExtendedPublicKey(privKeyBuffer); const ed25519PubKey = encodeEd25519Point(ed25519Key.point); const encodedPubKey = encodeEd25519Point(sharesData[0].final_user_point); From 74e55363734fdb4254c996e1966beebd1372de0c Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 11 Jul 2024 13:03:04 +0530 Subject: [PATCH 48/56] remove unused function --- src/Point.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/Point.ts b/src/Point.ts index 1c7f51f..6b03457 100644 --- a/src/Point.ts +++ b/src/Point.ts @@ -15,23 +15,6 @@ class Point { this.y = new BN(y, "hex"); this.ecCurve = ecCurve; } - - encode(enc: string): Buffer { - switch (enc) { - case "arr": - return Buffer.concat([ - Buffer.from("04", "hex"), - Buffer.from(this.x.toString("hex", 64), "hex"), - Buffer.from(this.y.toString("hex", 64), "hex"), - ]); - case "elliptic-compressed": { - const key = this.ecCurve.keyFromPublic({ x: this.x.toString("hex", 64), y: this.y.toString("hex", 64) }, "hex"); - return Buffer.from(key.getPublic(true, "hex")); - } - default: - throw new Error("encoding doesn't exist in Point"); - } - } } export default Point; From 4b98a63a38af0be55ff2c85346f3756fa458d5c8 Mon Sep 17 00:00:00 2001 From: himanshu Date: Thu, 11 Jul 2024 13:05:59 +0530 Subject: [PATCH 49/56] readd encode point function --- src/Point.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Point.ts b/src/Point.ts index 6b03457..1c7f51f 100644 --- a/src/Point.ts +++ b/src/Point.ts @@ -15,6 +15,23 @@ class Point { this.y = new BN(y, "hex"); this.ecCurve = ecCurve; } + + encode(enc: string): Buffer { + switch (enc) { + case "arr": + return Buffer.concat([ + Buffer.from("04", "hex"), + Buffer.from(this.x.toString("hex", 64), "hex"), + Buffer.from(this.y.toString("hex", 64), "hex"), + ]); + case "elliptic-compressed": { + const key = this.ecCurve.keyFromPublic({ x: this.x.toString("hex", 64), y: this.y.toString("hex", 64) }, "hex"); + return Buffer.from(key.getPublic(true, "hex")); + } + default: + throw new Error("encoding doesn't exist in Point"); + } + } } export default Point; From 095e77f503cf1df2e3a912168fded385b4411202 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 16 Jul 2024 10:10:46 +0530 Subject: [PATCH 50/56] fix node details import in tests --- test/sapphire_devnet_ed25519.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index e008174..6930bf6 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -1,5 +1,5 @@ import { TORUS_SAPPHIRE_NETWORK } from "@toruslabs/constants"; -import NodeManager from "@toruslabs/fetch-node-details"; +import { NodeDetailManager } from "@toruslabs/fetch-node-details"; import BN from "bn.js"; import base58 from "bs58"; import { expect } from "chai"; @@ -21,10 +21,10 @@ const HashEnabledVerifier = "torus-test-verifierid-hash"; describe("torus utils ed25519 sapphire devnet", function () { let torus: TorusUtils; - let TORUS_NODE_MANAGER: NodeManager; + let TORUS_NODE_MANAGER: NodeDetailManager; beforeEach("one time execution before all tests", async function () { - TORUS_NODE_MANAGER = new NodeManager({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET }); + TORUS_NODE_MANAGER = new NodeDetailManager({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET }); torus = new TorusUtils({ network: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_DEVNET, clientId: "YOUR_CLIENT_ID", From b509d35aa79244eddea90d7ed78fc98af5b3d9eb Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 22 Jul 2024 23:48:49 +0530 Subject: [PATCH 51/56] 15.0.0-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9171eb..4242623 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.0", "license": "MIT", "dependencies": { "@toruslabs/constants": "^14.0.0", diff --git a/package.json b/package.json index 381ddcc..b48f879 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "14.0.1", + "version": "15.0.0-alpha.0", "description": "Handle communication with torus nodes", "main": "dist/lib.cjs/index.js", "module": "dist/lib.esm/index.js", From 974cbc1afa3b0dee48ebef9da578a40f11ac0b7b Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 22 Jul 2024 23:51:21 +0530 Subject: [PATCH 52/56] Release 15.0.0-alpha.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4242623..ca2c5b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@toruslabs/torus.js", - "version": "15.0.0-alpha.0", + "version": "15.0.0-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@toruslabs/torus.js", - "version": "15.0.0-alpha.0", + "version": "15.0.0-alpha.1", "license": "MIT", "dependencies": { "@toruslabs/constants": "^14.0.0", diff --git a/package.json b/package.json index b48f879..b38c46c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@toruslabs/torus.js", - "version": "15.0.0-alpha.0", + "version": "15.0.0-alpha.1", "description": "Handle communication with torus nodes", "main": "dist/lib.cjs/index.js", "module": "dist/lib.esm/index.js", From 43f7444899ecbb2331c57d5a1cf1cf3edbf16b20 Mon Sep 17 00:00:00 2001 From: metalurgical <97008724+metalurgical@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:41:23 +0200 Subject: [PATCH 53/56] refactor: add types for extra params --- .gitignore | 1 + package-lock.json | 131 +++++++++++++++++++++++++++++------ src/TorusUtilsExtraParams.ts | 23 ++++++ src/helpers/nodeUtils.ts | 3 +- src/torus.ts | 25 ++++--- 5 files changed, 150 insertions(+), 33 deletions(-) create mode 100644 src/TorusUtilsExtraParams.ts diff --git a/.gitignore b/.gitignore index 9f6504c..a1b106c 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,4 @@ dist .tern-port .env.test +**/*.DS_Store diff --git a/package-lock.json b/package-lock.json index ca2c5b0..c97ff03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4204,15 +4204,14 @@ } }, "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" } }, "node_modules/asn1.js/node_modules/bn.js": { @@ -4734,22 +4733,81 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/browserify-sign/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/browserify-sign/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" } }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -5337,6 +5395,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -10753,16 +10817,33 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-asn1/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, "node_modules/parse-json": { @@ -11062,6 +11143,12 @@ "node": ">= 0.6.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", diff --git a/src/TorusUtilsExtraParams.ts b/src/TorusUtilsExtraParams.ts new file mode 100644 index 0000000..e9dc942 --- /dev/null +++ b/src/TorusUtilsExtraParams.ts @@ -0,0 +1,23 @@ +export interface TorusUtilsExtraParams { + nonce?: string; // farcaster + + message?: string; // farcaster + + signature?: string; // farcaster, passkey, webauthn + + clientDataJson?: string; // passkey, webauthn + + authenticatorData?: string; // passkey, webauhn + + publicKey?: string; // passkey, webauthn + + challenge?: string; // passkey, webauthn + + rpOrigin?: string; // passkey, webauthn + + rpId?: string; // passkey, webauthn + + session_token_exp_second?: number; + + timestamp?: number; // Signature +} diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index b194b48..08112e4 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -26,6 +26,7 @@ import { } from "../interfaces"; import log from "../loglevel"; import { Some } from "../some"; +import { TorusUtilsExtraParams } from "../TorusUtilsExtraParams"; import { calculateMedian, getProxyCoordinatorEndpointIndex, kCombinations, normalizeKeysResult, retryCommitment, thresholdSame } from "./common"; import { derivePubKey, @@ -174,7 +175,7 @@ export async function retrieveOrImportShare(params: { overrideExistingKey: boolean; nodePubkeys: INodePub[]; newImportedShares?: ImportedShare[]; - extraParams: Record; + extraParams: TorusUtilsExtraParams; }): Promise { const { legacyMetadataHost, diff --git a/src/torus.ts b/src/torus.ts index 54adecb..16456ac 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -34,6 +34,7 @@ import { VerifierParams, } from "./interfaces"; import log from "./loglevel"; +import { TorusUtilsExtraParams } from "./TorusUtilsExtraParams"; // Implement threshold logic wrappers around public APIs // of Torus nodes to handle malicious node responses @@ -117,7 +118,7 @@ class Torus { verifierParams: VerifierParams, idToken: string, nodePubkeys: INodePub[], - extraParams: Record = {}, + extraParams: TorusUtilsExtraParams = {}, useDkg?: boolean ): Promise { if (nodePubkeys.length === 0) { @@ -144,6 +145,11 @@ class Torus { if (!shouldUseDkg && nodePubkeys.length === 0) { throw new Error("nodePubkeys param is required"); } + + if (!extraParams.session_token_exp_second) { + extraParams.session_token_exp_second = Torus.sessionTime; + } + return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -162,10 +168,7 @@ class Torus { newImportedShares: [], overrideExistingKey: false, nodePubkeys, - extraParams: { - ...extraParams, - session_token_exp_second: Torus.sessionTime, - }, + extraParams, }); } @@ -186,12 +189,16 @@ class Torus { verifierParams: VerifierParams, idToken: string, newPrivateKey: string, - extraParams: Record = {} + extraParams: TorusUtilsExtraParams = {} ): Promise { if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } + if (!extraParams.session_token_exp_second) { + extraParams.session_token_exp_second = Torus.sessionTime; + } + let privKeyBuffer; if (this.keyType === KEY_TYPE.SECP256K1) { @@ -218,6 +225,7 @@ class Torus { throw new Error("invalid shares data for ed25519 key, public key is not matching after generating shares"); } } + return retrieveOrImportShare({ legacyMetadataHost: this.legacyMetadataHost, serverTimeOffset: this.serverTimeOffset, @@ -236,10 +244,7 @@ class Torus { overrideExistingKey: true, newImportedShares: sharesData, nodePubkeys, - extraParams: { - ...extraParams, - session_token_exp_second: Torus.sessionTime, - }, + extraParams, }); } From 141e9366031e47a12071fad77ccffd2f97e19234 Mon Sep 17 00:00:00 2001 From: himanshu Date: Mon, 29 Jul 2024 10:02:26 +0530 Subject: [PATCH 54/56] update param structure for retrieve shares and import key --- src/interfaces.ts | 26 ++++- src/torus.ts | 29 ++--- test/aqua.test.ts | 31 +++--- test/celeste.test.ts | 31 +++--- test/cyan.test.ts | 31 +++--- test/helpers.ts | 48 ++++++++- test/mainnet.test.ts | 31 +++--- test/onekey.test.ts | 49 ++++----- test/sapphire_devnet.test.ts | 153 ++++++++++++++------------ test/sapphire_devnet_ed25519.test.ts | 156 +++++++++++++++------------ test/sapphire_mainnet.test.ts | 89 +++++++-------- test/testnet.test.ts | 35 +++--- 12 files changed, 395 insertions(+), 314 deletions(-) diff --git a/src/interfaces.ts b/src/interfaces.ts index 62c30d6..02b8e13 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,8 +1,10 @@ -import type { TORUS_NETWORK_TYPE } from "@toruslabs/constants"; +import type { INodePub, TORUS_NETWORK_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import BN from "bn.js"; import { curve } from "elliptic"; +import { TorusUtilsExtraParams } from "./TorusUtilsExtraParams"; + export interface KeyIndex { index: string; service_group_id: string; @@ -250,3 +252,25 @@ export interface SapphireMetadataParams { }; signature?: string; } + +export interface ImportKeyParams { + endpoints: string[]; + nodeIndexes: number[]; + nodePubkeys: INodePub[]; + verifier: string; + verifierParams: VerifierParams; + idToken: string; + newPrivateKey: string; + extraParams?: TorusUtilsExtraParams; +} + +export interface RetrieveSharesParams { + endpoints: string[]; + indexes: number[]; + verifier: string; + verifierParams: VerifierParams; + idToken: string; + nodePubkeys: INodePub[]; + extraParams?: TorusUtilsExtraParams; + useDkg?: boolean; +} diff --git a/src/torus.ts b/src/torus.ts index 16456ac..3e4780a 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -25,16 +25,16 @@ import { } from "./helpers"; import { GetOrSetNonceResult, + ImportKeyParams, KeyType, LegacyVerifierLookupResponse, + RetrieveSharesParams, TorusCtorOptions, TorusKey, TorusPublicKey, v2NonceResultType, - VerifierParams, } from "./interfaces"; import log from "./loglevel"; -import { TorusUtilsExtraParams } from "./TorusUtilsExtraParams"; // Implement threshold logic wrappers around public APIs // of Torus nodes to handle malicious node responses @@ -111,16 +111,8 @@ class Torus { return torusKey.postboxKeyData.privKey; } - async retrieveShares( - endpoints: string[], - indexes: number[], - verifier: string, - verifierParams: VerifierParams, - idToken: string, - nodePubkeys: INodePub[], - extraParams: TorusUtilsExtraParams = {}, - useDkg?: boolean - ): Promise { + async retrieveShares(params: RetrieveSharesParams): Promise { + const { verifier, verifierParams, idToken, nodePubkeys, indexes, endpoints, useDkg, extraParams = {} } = params; if (nodePubkeys.length === 0) { throw new Error("nodePubkeys param is required"); } @@ -181,16 +173,9 @@ class Torus { return this.getNewPublicAddress(endpoints, { verifier, verifierId, extendedVerifierId }, this.enableOneKey); } - async importPrivateKey( - endpoints: string[], - nodeIndexes: number[], - nodePubkeys: INodePub[], - verifier: string, - verifierParams: VerifierParams, - idToken: string, - newPrivateKey: string, - extraParams: TorusUtilsExtraParams = {} - ): Promise { + async importPrivateKey(params: ImportKeyParams): Promise { + const { nodeIndexes, newPrivateKey, verifier, verifierParams, idToken, nodePubkeys, endpoints, extraParams = {} } = params; + if (endpoints.length !== nodeIndexes.length) { throw new Error(`length of endpoints array must be same as length of nodeIndexes array`); } diff --git a/test/aqua.test.ts b/test/aqua.test.ts index 4578009..765cb71 100644 --- a/test/aqua.test.ts +++ b/test/aqua.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -173,12 +173,7 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(result.finalKeyData.privKey).to.be.equal("f726ce4ac79ae4475d72633c94769a8817aff35eebe2d4790aed7b5d8a84aa1d"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -214,16 +209,18 @@ describe("torus utils aqua", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; diff --git a/test/celeste.test.ts b/test/celeste.test.ts index 7abb034..6f365f8 100644 --- a/test/celeste.test.ts +++ b/test/celeste.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -171,12 +171,7 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(result.finalKeyData.privKey).to.be.equal("0ae056aa938080c9e8bf6641261619e09fd510c91bb5aad14b0de9742085a914"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -213,16 +208,18 @@ describe("torus utils celeste", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); diff --git a/test/cyan.test.ts b/test/cyan.test.ts index 99b7df0..10aa432 100644 --- a/test/cyan.test.ts +++ b/test/cyan.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -176,12 +176,7 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -218,16 +213,18 @@ describe("torus utils cyan", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); diff --git a/test/helpers.ts b/test/helpers.ts index b796d38..a196b8a 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,9 +1,11 @@ +import { INodePub } from "@toruslabs/constants"; import { generateJsonRPCObject, post } from "@toruslabs/http-helpers"; import dotenv from "dotenv"; import jwt, { Algorithm } from "jsonwebtoken"; -import { JRPCResponse } from "../src"; +import { ImportKeyParams, JRPCResponse, RetrieveSharesParams, VerifierParams } from "../src"; import { config } from "../src/config"; +import { TorusUtilsExtraParams } from "../src/TorusUtilsExtraParams"; dotenv.config({ path: `.env.${process.env.NODE_ENV}` }); const jwtPrivateKey = `-----BEGIN PRIVATE KEY-----\nMEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCD7oLrcKae+jVZPGx52Cb/lKhdKxpXjl9eGNa1MlY57A==\n-----END PRIVATE KEY-----`; @@ -42,3 +44,47 @@ export const lookupVerifier = (endpoint: string, pubKeyX: string, pubKeyY: strin { logTracingHeader: config.logRequestTracing } ); }; + +export const getRetrieveSharesParams = ( + endpoints: string[], + indexes: number[], + verifier: string, + verifierParams: VerifierParams, + idToken: string, + nodePubkeys: INodePub[], + extraParams: TorusUtilsExtraParams = {}, + useDkg?: boolean +): RetrieveSharesParams => { + return { + endpoints, + indexes, + verifier, + verifierParams, + idToken, + nodePubkeys, + extraParams, + useDkg, + }; +}; + +export const getImportKeyParams = ( + endpoints: string[], + nodeIndexes: number[], + nodePubkeys: INodePub[], + verifier: string, + verifierParams: VerifierParams, + idToken: string, + newPrivateKey: string, + extraParams: TorusUtilsExtraParams = {} +): ImportKeyParams => { + return { + endpoints, + nodeIndexes, + nodePubkeys, + verifier, + verifierParams, + idToken, + newPrivateKey, + extraParams, + }; +}; diff --git a/test/mainnet.test.ts b/test/mainnet.test.ts index 0ef4379..f23dc9f 100644 --- a/test/mainnet.test.ts +++ b/test/mainnet.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -176,12 +176,7 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); delete result.sessionData; expect(result.metadata.serverTimeOffset).lessThan(20); @@ -217,16 +212,18 @@ describe("torus utils mainnet", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.oAuthKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); expect(result.finalKeyData.walletAddress).to.be.equal("0x621a4d458cFd345dAE831D9E756F10cC40A50381"); diff --git a/test/onekey.test.ts b/test/onekey.test.ts index 73a0fce..e8a9a1a 100644 --- a/test/onekey.test.ts +++ b/test/onekey.test.ts @@ -6,7 +6,7 @@ import faker from "faker"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_NODE_MANAGER = new NodeDetailManager({ network: TORUS_LEGACY_NETWORK.TESTNET, @@ -62,12 +62,7 @@ describe("torus onekey", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); @@ -115,16 +110,18 @@ describe("torus onekey", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); @@ -185,7 +182,9 @@ describe("torus onekey", function () { const token = generateIdToken(email, "ES256"); const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: email }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); - const result = await torus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub); + const result = await torus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) + ); expect(!result.metadata.nonce.eq(new BN("0"))); expect(result.metadata.typeOfUser).to.equal("v2"); expect(result.metadata.upgraded).to.equal(false); @@ -200,12 +199,14 @@ describe("torus onekey", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: "Jonathan.Nolan@hotmail.com" }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: "Jonathan.Nolan@hotmail.com" }, - token, - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: "Jonathan.Nolan@hotmail.com" }, + token, + torusNodePub + ) ); expect(retrieveSharesResponse.metadata.serverTimeOffset).lessThan(20); delete retrieveSharesResponse.metadata.serverTimeOffset; diff --git a/test/sapphire_devnet.test.ts b/test/sapphire_devnet.test.ts index 385a571..751e8ad 100644 --- a/test/sapphire_devnet.test.ts +++ b/test/sapphire_devnet.test.ts @@ -7,7 +7,7 @@ import faker from "faker"; import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken, lookupVerifier } from "./helpers"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "devnettestuser@tor.us"; const TORUS_HASH_ENABLED_TEST_EMAIL = "saasas@tr.us"; @@ -90,12 +90,7 @@ describe("torus utils sapphire devnet", function () { }); const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes, torusNodePub } = await LEGACY_TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const retrieveSharesResponse = await legacyTorus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) ); expect(retrieveSharesResponse.finalKeyData.privKey).to.be.equal("dca7f29d234dc71561efe1a874d872bf34f6528bc042fe35e57197eac1f14eb9"); delete retrieveSharesResponse.sessionData; @@ -325,12 +320,14 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; @@ -377,14 +374,16 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - nodeDetails.torusNodePub, - {}, - false + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) ); const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); @@ -398,14 +397,16 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - nodeDetails.torusNodePub, - {}, - false + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) ); const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); @@ -419,12 +420,14 @@ describe("torus utils sapphire devnet", function () { const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; torusNodeEndpoints[1] = "https://example.com"; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; @@ -474,12 +477,14 @@ describe("torus utils sapphire devnet", function () { TorusUtils.setSessionTime(customSessionTime); // 1hr const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); const signatures = result.sessionData.sessionTokenData.map((s) => ({ data: s.token, sig: s.signature })); @@ -501,13 +506,15 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - privHex + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + privHex + ) ); expect(result.finalKeyData.privKey).to.be.equal(privHex); const result1 = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, { verifier: TORUS_TEST_VERIFIER, verifierId: email }); @@ -572,12 +579,14 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.not.equal(null); expect(result.oAuthKeyData.walletAddress).to.not.equal(null); @@ -673,12 +682,14 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - HashEnabledVerifier, - { verifier_id: TORUS_HASH_ENABLED_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_HASH_ENABLED_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; @@ -727,16 +738,18 @@ describe("torus utils sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: email, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: email, - }, - hashedIdToken.substring(2), - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 6930bf6..5720b72 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -7,7 +7,7 @@ import faker from "faker"; import { keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken, lookupVerifier } from "./helpers"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams, lookupVerifier } from "./helpers"; const TORUS_TEST_EMAIL = "ed25519testuser@tor.us"; const TORUS_TEST_EMAIL_HASHED = "ed25519testuserhashed19@tor.us"; @@ -77,25 +77,29 @@ describe("torus utils ed25519 sapphire devnet", function () { const decodedKey = Buffer.from(base58.decode(privB58)); const seedKey = decodedKey.subarray(0, 32).toString("hex"); const result = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - seedKey + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + seedKey + ) ); expect(result.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); expect(result.finalKeyData.privKey).to.be.equal(seedKey); const token1 = generateIdToken(email, "ES256"); const result1 = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token1, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token1, + nodeDetails.torusNodePub + ) ); expect(result1.finalKeyData.walletAddress).eql("3TTBP4g4UZNH1Tga1D4D6tBGrXUpVXcWt1PX2W19CRqM"); expect(result.finalKeyData.privKey).to.be.equal(seedKey); @@ -115,12 +119,14 @@ describe("torus utils ed25519 sapphire devnet", function () { const token = generateIdToken(`${testEmail}`, "ES256"); const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: testEmail }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: testEmail }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; @@ -171,12 +177,14 @@ describe("torus utils ed25519 sapphire devnet", function () { expect(result.finalKeyData.walletAddress).to.not.equal(""); expect(result.finalKeyData.walletAddress).to.not.equal(null); const result2 = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); }); @@ -188,14 +196,16 @@ describe("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - nodeDetails.torusNodePub, - {}, - false + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + nodeDetails.torusNodePub, + {}, + false + ) ); const publicResult = await torus.getPublicAddress(torusNodeEndpoints, nodeDetails.torusNodePub, verifierDetails); @@ -209,12 +219,14 @@ describe("torus utils ed25519 sapphire devnet", function () { const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; torusNodeEndpoints[1] = "https://example.com"; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.be.equal("ea39cc89d2d8b8403858d1c518fe82e2500cc83e472ba86d006323b57835a519"); }); @@ -275,12 +287,14 @@ describe("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.not.equal(null); expect(result.oAuthKeyData.walletAddress).to.not.equal(null); @@ -290,12 +304,14 @@ describe("torus utils ed25519 sapphire devnet", function () { const token2 = generateIdToken(email, "ES256"); const result2 = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token2, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token2, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.equal(result2.finalKeyData.privKey); expect(result.oAuthKeyData.walletAddress).to.equal(result2.finalKeyData.walletAddress); @@ -347,12 +363,14 @@ describe("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: HashEnabledVerifier, verifierId: TORUS_TEST_EMAIL_HASHED }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - HashEnabledVerifier, - { verifier_id: TORUS_TEST_EMAIL_HASHED }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_TEST_EMAIL_HASHED }, + token, + nodeDetails.torusNodePub + ) ); delete result.metadata.serverTimeOffset; expect(result).eql({ @@ -412,16 +430,18 @@ describe("torus utils ed25519 sapphire devnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: email, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: email, - }, - hashedIdToken.substring(2), - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.walletAddress).to.not.equal(null); expect(result.finalKeyData.walletAddress).to.not.equal(""); diff --git a/test/sapphire_mainnet.test.ts b/test/sapphire_mainnet.test.ts index 5b1c42e..0fdade6 100644 --- a/test/sapphire_mainnet.test.ts +++ b/test/sapphire_mainnet.test.ts @@ -7,7 +7,7 @@ import faker from "faker"; import { generatePrivateKey, keccak256 } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getImportKeyParams, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "hello@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -71,13 +71,15 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifier: TORUS_TEST_VERIFIER, verifierId: email }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.importPrivateKey( - torusNodeEndpoints, - nodeDetails.torusIndexes, - nodeDetails.torusNodePub, - TORUS_TEST_VERIFIER, - { verifier_id: email }, - token, - privHex + getImportKeyParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + nodeDetails.torusNodePub, + TORUS_TEST_VERIFIER, + { verifier_id: email }, + token, + privHex + ) ); expect(result.finalKeyData.privKey).to.be.equal(privHex); }); @@ -155,12 +157,14 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails({ verifierId: email, verifier: TORUS_TEST_VERIFIER }); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { extended_verifier_id: tssVerifierId, verifier_id: email }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { extended_verifier_id: tssVerifierId, verifier_id: email }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.not.equal(null); expect(result.oAuthKeyData.walletAddress).to.not.equal(null); @@ -241,12 +245,14 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - HashEnabledVerifier, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + HashEnabledVerifier, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.privKey).to.be.equal("13941ecd812b08d8a33a20bc975f0cd1c3f82de25b20c0c863ba5f21580b65f6"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -292,12 +298,7 @@ describe("torus utils sapphire mainnet", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(result.finalKeyData.privKey).to.be.equal("dfb39b84e0c64b8c44605151bf8670ae6eda232056265434729b6a8a50fa3419"); expect(result.metadata.serverTimeOffset).lessThan(20); @@ -345,16 +346,18 @@ describe("torus utils sapphire mainnet", function () { const nodeDetails = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const torusNodeEndpoints = nodeDetails.torusNodeSSSEndpoints; const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: email, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: email, - }, - hashedIdToken.substring(2), - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: email, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: email, + }, + hashedIdToken.substring(2), + nodeDetails.torusNodePub + ) ); expect(result.finalKeyData.walletAddress).to.not.equal(null); expect(result.finalKeyData.walletAddress).to.not.equal(""); @@ -376,12 +379,14 @@ describe("torus utils sapphire mainnet", function () { TorusUtils.setSessionTime(customSessionTime); // 1hr const result = await torus.retrieveShares( - torusNodeEndpoints, - nodeDetails.torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - nodeDetails.torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + nodeDetails.torusIndexes, + TORUS_TEST_VERIFIER, + { verifier_id: TORUS_TEST_EMAIL }, + token, + nodeDetails.torusNodePub + ) ); const signatures = result.sessionData.sessionTokenData.map((s) => ({ data: s.token, sig: s.signature })); diff --git a/test/testnet.test.ts b/test/testnet.test.ts index 8ca3f0b..e495699 100644 --- a/test/testnet.test.ts +++ b/test/testnet.test.ts @@ -8,7 +8,7 @@ import { useFakeTimers } from "sinon"; import { keccak256, TorusPublicKey } from "../src"; import TorusUtils from "../src/torus"; -import { generateIdToken } from "./helpers"; +import { generateIdToken, getRetrieveSharesParams } from "./helpers"; const TORUS_TEST_EMAIL = "archit1@tor.us"; const TORUS_TEST_VERIFIER = "torus-test-health"; @@ -178,12 +178,7 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier: TORUS_TEST_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_VERIFIER, - { verifier_id: TORUS_TEST_EMAIL }, - token, - torusNodePub + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: TORUS_TEST_EMAIL }, token, torusNodePub) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; @@ -222,16 +217,18 @@ describe("torus utils migrated testnet on sapphire", function () { const verifierDetails = { verifier: TORUS_TEST_AGGREGATE_VERIFIER, verifierId: TORUS_TEST_EMAIL }; const { torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); const result = await torus.retrieveShares( - torusNodeEndpoints, - torusIndexes, - TORUS_TEST_AGGREGATE_VERIFIER, - { - verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], - sub_verifier_ids: [TORUS_TEST_VERIFIER], - verifier_id: TORUS_TEST_EMAIL, - }, - hashedIdToken.substring(2), - torusNodePub + getRetrieveSharesParams( + torusNodeEndpoints, + torusIndexes, + TORUS_TEST_AGGREGATE_VERIFIER, + { + verify_params: [{ verifier_id: TORUS_TEST_EMAIL, idtoken: idToken }], + sub_verifier_ids: [TORUS_TEST_VERIFIER], + verifier_id: TORUS_TEST_EMAIL, + }, + hashedIdToken.substring(2), + torusNodePub + ) ); expect(result.metadata.serverTimeOffset).lessThan(20); delete result.metadata.serverTimeOffset; @@ -280,7 +277,9 @@ describe("torus utils migrated testnet on sapphire", function () { }); const { torusNodeSSSEndpoints: torusNodeEndpoints, torusIndexes, torusNodePub } = await TORUS_NODE_MANAGER.getNodeDetails(verifierDetails); try { - await legacyTorus.retrieveShares(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub); + await legacyTorus.retrieveShares( + getRetrieveSharesParams(torusNodeEndpoints, torusIndexes, TORUS_TEST_VERIFIER, { verifier_id: email }, token, torusNodePub) + ); fail("should not reach here"); } catch (err) { expect((err as { status: number }).status).to.equal(403); From 7fa95fb0c43408a539e052febed688064442f911 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 30 Jul 2024 09:53:41 +0530 Subject: [PATCH 55/56] fix test --- test/sapphire_devnet_ed25519.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sapphire_devnet_ed25519.test.ts b/test/sapphire_devnet_ed25519.test.ts index 5720b72..c8021a7 100644 --- a/test/sapphire_devnet_ed25519.test.ts +++ b/test/sapphire_devnet_ed25519.test.ts @@ -66,7 +66,7 @@ describe("torus utils ed25519 sapphire devnet", function () { }); it("should be able to import a key for a new user", async function () { - const email = "Willa_Funk1289@gmail.com"; + const email = faker.internet.email(); const token = generateIdToken(email, "ES256"); // const privKeyBuffer = new BN(generatePrivateKey(ec, Buffer)); // key exported from phantom wallet From fcaba4b8ab76280279071bd947fa300c8b277a77 Mon Sep 17 00:00:00 2001 From: Chaitanya Potti Date: Tue, 30 Jul 2024 19:51:23 +0800 Subject: [PATCH 56/56] minor refactor --- package-lock.json | 58 ++++++++++---------- package.json | 12 ++--- src/Polynomial.ts | 4 +- src/helpers/common.ts | 11 +++- src/helpers/keyUtils.ts | 72 ++++++------------------- src/helpers/langrangeInterpolatePoly.ts | 28 +++++----- src/helpers/metadataUtils.ts | 50 ++++++++++++----- src/helpers/nodeUtils.ts | 52 +++++++++--------- src/interfaces.ts | 3 ++ src/torus.ts | 2 +- 10 files changed, 146 insertions(+), 146 deletions(-) diff --git a/package-lock.json b/package-lock.json index c97ff03..a3f80fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,15 +13,15 @@ "@toruslabs/eccrypto": "^5.0.4", "@toruslabs/http-helpers": "^7.0.0", "bn.js": "^5.2.1", - "bs58": "^5.0.0", - "elliptic": "^6.5.5", + "bs58": "^6.0.0", + "elliptic": "^6.5.6", "ethereum-cryptography": "^2.2.1", "json-stable-stringify": "^1.1.1", "loglevel": "^1.9.1" }, "devDependencies": { "@babel/register": "^7.24.6", - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.0", "@toruslabs/config": "^2.1.0", "@toruslabs/eslint-config-typescript": "^3.3.1", "@toruslabs/fetch-node-details": "^14.0.1", @@ -38,15 +38,15 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "faker": "^5.5.3", - "husky": "^9.0.11", + "husky": "^9.1.4", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.7", - "mocha": "^10.6.0", + "mocha": "^10.7.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", "sinon": "^18.0.0", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=18.x", @@ -1815,9 +1815,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -4451,9 +4451,9 @@ "dev": true }, "node_modules/base-x": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", - "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -4850,11 +4850,11 @@ } }, "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", "dependencies": { - "base-x": "^4.0.0" + "base-x": "^5.0.0" } }, "node_modules/buffer": { @@ -5888,9 +5888,9 @@ "dev": true }, "node_modules/elliptic": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", - "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "version": "6.5.6", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.6.tgz", + "integrity": "sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -7890,12 +7890,12 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.4.tgz", + "integrity": "sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==", "dev": true, "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -10015,9 +10015,9 @@ } }, "node_modules/mocha": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz", - "integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==", + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", + "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", "dev": true, "dependencies": { "ansi-colors": "^4.1.3", @@ -13025,9 +13025,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index b38c46c..a408260 100644 --- a/package.json +++ b/package.json @@ -28,15 +28,15 @@ "@toruslabs/eccrypto": "^5.0.4", "@toruslabs/http-helpers": "^7.0.0", "bn.js": "^5.2.1", - "elliptic": "^6.5.5", - "bs58": "^5.0.0", + "elliptic": "^6.5.6", + "bs58": "^6.0.0", "ethereum-cryptography": "^2.2.1", "json-stable-stringify": "^1.1.1", "loglevel": "^1.9.1" }, "devDependencies": { "@babel/register": "^7.24.6", - "@babel/runtime": "^7.24.8", + "@babel/runtime": "^7.25.0", "@toruslabs/config": "^2.1.0", "@toruslabs/eslint-config-typescript": "^3.3.1", "@toruslabs/fetch-node-details": "^14.0.1", @@ -53,15 +53,15 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "faker": "^5.5.3", - "husky": "^9.0.11", + "husky": "^9.1.4", "jsonwebtoken": "^9.0.2", "lint-staged": "^15.2.7", - "mocha": "^10.6.0", + "mocha": "^10.7.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", "sinon": "^18.0.0", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "repository": { "type": "git", diff --git a/src/Polynomial.ts b/src/Polynomial.ts index b5237f7..c86ab4f 100644 --- a/src/Polynomial.ts +++ b/src/Polynomial.ts @@ -30,9 +30,9 @@ class Polynomial { for (let i = 1; i < this.polynomial.length; i += 1) { const tmp = xi.mul(this.polynomial[i]); sum = sum.add(tmp); - sum = sum.umod(this.ecCurve.curve.n); + sum = sum.umod(this.ecCurve.n); xi = xi.mul(new BN(tmpX)); - xi = xi.umod(this.ecCurve.curve.n); + xi = xi.umod(this.ecCurve.n); } return sum; } diff --git a/src/helpers/common.ts b/src/helpers/common.ts index 1ecb58c..8d37f0a 100644 --- a/src/helpers/common.ts +++ b/src/helpers/common.ts @@ -2,10 +2,19 @@ import { JRPCResponse, KEY_TYPE } from "@toruslabs/constants"; import { Ecies } from "@toruslabs/eccrypto"; import { BN } from "bn.js"; import { ec as EC } from "elliptic"; +import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import JsonStringify from "json-stable-stringify"; import { CommitmentRequestResult, EciesHex, KeyType, VerifierLookupResponse } from "../interfaces"; -import { keccak256 } from "./keyUtils"; + +export function keccak256(a: Buffer): string { + const hash = Buffer.from(keccakHash(a)).toString("hex"); + return `0x${hash}`; +} + +export const generatePrivateKey = (ecCurve: EC, buf: typeof Buffer): Buffer => { + return ecCurve.genKeyPair().getPrivate().toArrayLike(buf); +}; export const getKeyCurve = (keyType: KeyType) => { if (keyType === KEY_TYPE.ED25519) { diff --git a/src/helpers/keyUtils.ts b/src/helpers/keyUtils.ts index e506bec..12810c6 100644 --- a/src/helpers/keyUtils.ts +++ b/src/helpers/keyUtils.ts @@ -9,18 +9,9 @@ import stringify from "json-stable-stringify"; import log from "loglevel"; import { EncryptedSeed, ImportedShare, KeyType, PrivateKeyData } from "../interfaces"; -import { encParamsBufToHex, getKeyCurve } from "./common"; +import { encParamsBufToHex, generatePrivateKey, getKeyCurve, keccak256 } from "./common"; import { generateRandomPolynomial } from "./langrangeInterpolatePoly"; -import { generateNonceMetadataParams } from "./metadataUtils"; - -export function keccak256(a: Buffer): string { - const hash = Buffer.from(keccakHash(a)).toString("hex"); - return `0x${hash}`; -} - -export const generatePrivateKey = (ecCurve: EC, buf: typeof Buffer): Buffer => { - return ecCurve.genKeyPair().getPrivate().toArrayLike(buf); -}; +import { generateNonceMetadataParams, getSecpKeyFromEd25519 } from "./metadataUtils"; export function stripHexPrefix(str: string): string { return str.startsWith("0x") ? str.slice(2) : str; @@ -81,30 +72,6 @@ export function getEd25519ExtendedPublicKey(keyBuffer: Buffer): { return { scalar, point }; } -export const getSecpKeyFromEd25519 = ( - ed25519Scalar: BN -): { - scalar: BN; - point: curve.base.BasePoint; -} => { - const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); - - const ed25519Key = ed25519Scalar.toString("hex", 64); - const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); - const secpKey = new BN(keyHash).umod(secp256k1Curve.curve.n).toString("hex", 64); - const bufferKey = Buffer.from(secpKey, "hex"); - - const secpKeyPair = secp256k1Curve.keyFromPrivate(bufferKey); - - if (bufferKey.length < 32) { - throw new Error("Invalid key length, please try again"); - } - return { - scalar: secpKeyPair.getPrivate(), - point: secpKeyPair.getPublic(), - }; -}; - export function encodeEd25519Point(point: curve.base.BasePoint) { const ed25519Curve = getKeyCurve(KEY_TYPE.ED25519); @@ -149,11 +116,11 @@ export const generateSecp256k1KeyData = async (scalarBuffer: Buffer): Promise { @@ -230,7 +192,7 @@ export const generateShares = async ( for (const nodeIndex of nodeIndexes) { nodeIndexesBn.push(new BN(nodeIndex)); } - const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex").padStart(64, "0")).getPublic(); + const oAuthPubKey = ecCurve.keyFromPrivate(oAuthKey.toString("hex", 64), "hex").getPublic(); const poly = generateRandomPolynomial(ecCurve, degree, oAuthKey); const shares = poly.generateShares(nodeIndexesBn); const nonceParams = generateNonceMetadataParams(serverTimeOffset, "getOrSetNonce", metadataSigningKey, keyType, metadataNonce, encryptedSeed); @@ -248,7 +210,7 @@ export const generateShares = async ( ); } const encShares = await Promise.all(encPromises); - for (let i = 0; i < nodeIndexesBn.length; i++) { + for (let i = 0; i < nodeIndexesBn.length; i += 1) { const shareJson = shares[nodeIndexesBn[i].toString("hex", 64)].toJSON() as Record; const encParams = encShares[i]; const encParamsMetadata = encParamsBufToHex(encParams); diff --git a/src/helpers/langrangeInterpolatePoly.ts b/src/helpers/langrangeInterpolatePoly.ts index 28290e6..568f342 100644 --- a/src/helpers/langrangeInterpolatePoly.ts +++ b/src/helpers/langrangeInterpolatePoly.ts @@ -4,7 +4,7 @@ import { ec as EC } from "elliptic"; import Point from "../Point"; import Polynomial from "../Polynomial"; import Share from "../Share"; -import { generatePrivateKey } from "."; +import { generatePrivateKey } from "./common"; function generatePrivateExcludingIndexes(shareIndexes: BN[], ecCurve: EC): BN { const key = new BN(generatePrivateKey(ecCurve, Buffer)); @@ -22,9 +22,9 @@ const denominator = (ecCurve: EC, i: number, innerPoints: Point[]) => { if (i !== j) { let tmp = new BN(xi); tmp = tmp.sub(innerPoints[j].x); - tmp = tmp.umod(ecCurve.curve.n); + tmp = tmp.umod(ecCurve.n); result = result.mul(tmp); - result = result.umod(ecCurve.curve.n); + result = result.umod(ecCurve.n); } } return result; @@ -36,7 +36,7 @@ const interpolationPoly = (ecCurve: EC, i: number, innerPoints: Point[]): BN[] = if (d.cmp(new BN(0)) === 0) { throw new Error("Denominator for interpolationPoly is 0"); } - coefficients[0] = d.invm(ecCurve.curve.n); + coefficients[0] = d.invm(ecCurve.n); for (let k = 0; k < innerPoints.length; k += 1) { const newCoefficients = generateEmptyBNArray(innerPoints.length); if (k !== i) { @@ -48,10 +48,10 @@ const interpolationPoly = (ecCurve: EC, i: number, innerPoints: Point[]): BN[] = } j -= 1; for (; j >= 0; j -= 1) { - newCoefficients[j + 1] = newCoefficients[j + 1].add(coefficients[j]).umod(ecCurve.curve.n); + newCoefficients[j + 1] = newCoefficients[j + 1].add(coefficients[j]).umod(ecCurve.n); let tmp = new BN(innerPoints[k].x); - tmp = tmp.mul(coefficients[j]).umod(ecCurve.curve.n); - newCoefficients[j] = newCoefficients[j].sub(tmp).umod(ecCurve.curve.n); + tmp = tmp.mul(coefficients[j]).umod(ecCurve.n); + newCoefficients[j] = newCoefficients[j].sub(tmp).umod(ecCurve.n); } coefficients = newCoefficients; } @@ -73,7 +73,7 @@ const lagrange = (ecCurve: EC, unsortedPoints: Point[]) => { for (let k = 0; k < sortedPoints.length; k += 1) { let tmp = new BN(sortedPoints[i].y); tmp = tmp.mul(coefficients[k]); - polynomial[k] = polynomial[k].add(tmp).umod(ecCurve.curve.n); + polynomial[k] = polynomial[k].add(tmp).umod(ecCurve.n); } } return new Polynomial(polynomial, ecCurve); @@ -94,17 +94,17 @@ export function lagrangeInterpolation(ecCurve: EC, shares: BN[], nodeIndex: BN[] for (let j = 0; j < shares.length; j += 1) { if (i !== j) { upper = upper.mul(nodeIndex[j].neg()); - upper = upper.umod(ecCurve.curve.n); + upper = upper.umod(ecCurve.n); let temp = nodeIndex[i].sub(nodeIndex[j]); - temp = temp.umod(ecCurve.curve.n); - lower = lower.mul(temp).umod(ecCurve.curve.n); + temp = temp.umod(ecCurve.n); + lower = lower.mul(temp).umod(ecCurve.n); } } - let delta = upper.mul(lower.invm(ecCurve.curve.n)).umod(ecCurve.curve.n); - delta = delta.mul(shares[i]).umod(ecCurve.curve.n); + let delta = upper.mul(lower.invm(ecCurve.n)).umod(ecCurve.n); + delta = delta.mul(shares[i]).umod(ecCurve.n); secret = secret.add(delta); } - return secret.umod(ecCurve.curve.n); + return secret.umod(ecCurve.n); } // generateRandomPolynomial - determinisiticShares are assumed random diff --git a/src/helpers/metadataUtils.ts b/src/helpers/metadataUtils.ts index 2e959fd..ed992c1 100644 --- a/src/helpers/metadataUtils.ts +++ b/src/helpers/metadataUtils.ts @@ -2,7 +2,8 @@ import { KEY_TYPE, LEGACY_NETWORKS_ROUTE_MAP, TORUS_LEGACY_NETWORK_TYPE, TORUS_N import { decrypt } from "@toruslabs/eccrypto"; import { Data, post } from "@toruslabs/http-helpers"; import BN from "bn.js"; -import { ec as EC } from "elliptic"; +import { curve, ec as EC } from "elliptic"; +import { keccak256 as keccakHash } from "ethereum-cryptography/keccak"; import stringify from "json-stable-stringify"; import log from "loglevel"; @@ -17,8 +18,32 @@ import { SapphireMetadataParams, SetNonceData, } from "../interfaces"; -import { encParamsHexToBuf, getKeyCurve } from "./common"; -import { getSecpKeyFromEd25519, keccak256 } from "./keyUtils"; +import { encParamsHexToBuf, getKeyCurve, keccak256 } from "./common"; + +export const getSecpKeyFromEd25519 = ( + ed25519Scalar: BN +): { + scalar: BN; + point: curve.base.BasePoint; +} => { + const secp256k1Curve = getKeyCurve(KEY_TYPE.SECP256K1); + + const ed25519Key = ed25519Scalar.toString("hex", 64); + const keyHash = keccakHash(Buffer.from(ed25519Key, "hex")); + const secpKey = new BN(keyHash).umod(secp256k1Curve.n).toString("hex", 64); + const bufferKey = Buffer.from(secpKey, "hex"); + + const secpKeyPair = secp256k1Curve.keyFromPrivate(bufferKey); + + if (bufferKey.length < 32) { + throw new Error(`Key length must be less than 32. got ${bufferKey.length}`); + } + return { + scalar: secpKeyPair.getPrivate(), + point: secpKeyPair.getPublic(), + }; +}; + export function convertMetadataToNonce(params: { message?: string }) { if (!params || !params.message) { return new BN(0); @@ -44,6 +69,7 @@ export async function decryptNodeDataWithPadding(eciesData: EciesHex, ciphertext }); return decryptedSigBuffer; } catch (error) { + // ciphertext can be any length. not just 64. depends on input. we have this for legacy reason const ciphertextHexPadding = ciphertextHex.padStart(64, "0"); log.warn("Failed to decrypt padded share cipher", error); @@ -53,7 +79,7 @@ export async function decryptNodeDataWithPadding(eciesData: EciesHex, ciphertext } export function generateMetadataParams(ecCurve: EC, serverTimeOffset: number, message: string, privateKey: BN): MetadataParams { - const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64)); + const key = ecCurve.keyFromPrivate(privateKey.toString("hex", 64), "hex"); const setData = { data: message, timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), @@ -93,7 +119,7 @@ export function generateNonceMetadataParams( seed?: string ): NonceMetadataParams { // metadata only uses secp for sig validation - const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privateKey.toString("hex", 64)); + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privateKey.toString("hex", 64), "hex"); const setData: Partial = { operation, timestamp: new BN(~~(serverTimeOffset + Date.now() / 1000)).toString(16), @@ -167,7 +193,7 @@ export async function getOrSetNonce( const data = { pub_key_X: X, pub_key_Y: Y, - set_data: { operation: "getNonce" }, + set_data: { operation }, key_type: keyType, }; return post(`${metadataHost}/get_or_set_nonce`, data, undefined, { useAPIKey: true }); @@ -187,13 +213,8 @@ export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { const decryptionKey = getSecpKeyFromEd25519(finalUserKey); const seedUtf8 = Buffer.from(seedBase64, "base64").toString("utf-8"); const seedJson = JSON.parse(seedUtf8) as EncryptedSeed; - const bufferMetadata = { - ephemPublicKey: Buffer.from(seedJson.metadata.ephemPublicKey, "hex"), - iv: Buffer.from(seedJson.metadata.iv, "hex"), - mac: Buffer.from(seedJson.metadata.mac, "hex"), - mode: "AES256", - }; - const bufferKey = Buffer.from(decryptionKey.scalar.toString("hex", 64), "hex"); + const bufferMetadata = { ...encParamsHexToBuf(seedJson.metadata), mode: "AES256" }; + const bufferKey = decryptionKey.scalar.toArrayLike(Buffer); const decText = await decrypt(bufferKey, { ...bufferMetadata, ciphertext: Buffer.from(seedJson.enc_text, "hex"), @@ -201,6 +222,7 @@ export const decryptSeedData = async (seedBase64: string, finalUserKey: BN) => { return decText; }; + export async function getOrSetSapphireMetadataNonce( network: TORUS_NETWORK_TYPE, X: string, @@ -218,7 +240,7 @@ export async function getOrSetSapphireMetadataNonce( set_data: { operation: "getOrSetNonce" }, }; if (privKey) { - const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privKey.toString("hex", 64)); + const key = getKeyCurve(KEY_TYPE.SECP256K1).keyFromPrivate(privKey.toString("hex", 64), "hex"); const setData = { operation: "getOrSetNonce", diff --git a/src/helpers/nodeUtils.ts b/src/helpers/nodeUtils.ts index 08112e4..ffc7cc3 100644 --- a/src/helpers/nodeUtils.ts +++ b/src/helpers/nodeUtils.ts @@ -27,16 +27,17 @@ import { import log from "../loglevel"; import { Some } from "../some"; import { TorusUtilsExtraParams } from "../TorusUtilsExtraParams"; -import { calculateMedian, getProxyCoordinatorEndpointIndex, kCombinations, normalizeKeysResult, retryCommitment, thresholdSame } from "./common"; import { - derivePubKey, - generateAddressFromPrivKey, - generateAddressFromPubKey, + calculateMedian, generatePrivateKey, - generateShares, - getSecpKeyFromEd25519, + getProxyCoordinatorEndpointIndex, + kCombinations, keccak256, -} from "./keyUtils"; + normalizeKeysResult, + retryCommitment, + thresholdSame, +} from "./common"; +import { derivePubKey, generateAddressFromPrivKey, generateAddressFromPubKey, generateShares } from "./keyUtils"; import { lagrangeInterpolation } from "./langrangeInterpolatePoly"; import { decryptNodeData, @@ -45,6 +46,7 @@ import { getMetadata, getOrSetNonce, getOrSetSapphireMetadataNonce, + getSecpKeyFromEd25519, } from "./metadataUtils"; export const GetPubKeyOrKeyAssign = async (params: { @@ -218,13 +220,16 @@ export async function retrieveOrImportShare(params: { const pubKeyX = pubKey.slice(2, 66); const pubKeyY = pubKey.slice(66); let finalImportedShares: ImportedShare[] = []; + const threeFourthsThreshold = ~~((endpoints.length * 3) / 4) + 1; + const halfThreshold = ~~(endpoints.length / 2) + 1; - if (newImportedShares.length > 0) { + if (newImportedShares?.length > 0) { if (newImportedShares.length !== endpoints.length) { throw new Error("Invalid imported shares length"); } finalImportedShares = newImportedShares; } else if (!useDkg) { + // TODO: why use getrandombytes here? const bufferKey = keyType === KEY_TYPE.SECP256K1 ? generatePrivateKey(ecCurve, Buffer) : await getRandomBytes(32); const generatedShares = await generateShares(ecCurve, keyType, serverTimeOffset, indexes, nodePubkeys, Buffer.from(bufferKey)); finalImportedShares = [...finalImportedShares, ...generatedShares]; @@ -289,7 +294,7 @@ export async function retrieveOrImportShare(params: { if (requiredNodeResult) { return Promise.resolve(resultArr); } - } else if (!overrideExistingKey && completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + } else if (!overrideExistingKey && completedRequests.length >= threeFourthsThreshold) { const nodeSigs: CommitmentRequestResult[] = []; for (let i = 0; i < completedRequests.length; i += 1) { const x = completedRequests[i]; @@ -300,7 +305,7 @@ export async function retrieveOrImportShare(params: { } const existingPubKey = thresholdSame( nodeSigs.map((x) => x && x.pub_key_x), - ~~(endpoints.length / 2) + 1 + halfThreshold ); const proxyEndpointNum = getProxyCoordinatorEndpointIndex(endpoints, verifier, verifierParams.verifier_id); // for import shares, proxy node response is required. @@ -321,7 +326,7 @@ export async function retrieveOrImportShare(params: { } } } - } else if (completedRequests.length >= ~~((endpoints.length * 3) / 4) + 1) { + } else if (completedRequests.length >= threeFourthsThreshold) { // this case is for dkg keys const requiredNodeResult = completedRequests.find((resp: void | JRPCResponse) => { if (resp) { @@ -350,7 +355,7 @@ export async function retrieveOrImportShare(params: { // if user's account already const existingPubKey = thresholdSame( nodeSigs.map((x) => x && x.pub_key_x), - ~~(endpoints.length / 2) + 1 + halfThreshold ); // can only import shares if override existing key is allowed or for new non dkg registration @@ -475,7 +480,7 @@ export async function retrieveOrImportShare(params: { return undefined; }); - const thresholdPublicKey = thresholdSame(pubkeys, ~~(endpoints.length / 2) + 1); + const thresholdPublicKey = thresholdSame(pubkeys, halfThreshold); if (!thresholdPublicKey) { throw new Error("invalid result from nodes, threshold number of public key results are not matching"); @@ -492,7 +497,7 @@ export async function retrieveOrImportShare(params: { } }); - const thresholdReqCount = canImportedShares ? endpoints.length : ~~(endpoints.length / 2) + 1; + const thresholdReqCount = canImportedShares ? endpoints.length : halfThreshold; // optimistically run lagrange interpolation once threshold number of shares have been received // this is matched against the user public key to ensure that shares are consistent // Note: no need of thresholdMetadataNonce for extended_verifier_id key @@ -578,9 +583,8 @@ export async function retrieveOrImportShare(params: { return false; }); - const minThresholdRequired = ~~(endpoints.length / 2) + 1; - if (!verifierParams.extended_verifier_id && validSigs.length < minThresholdRequired) { - throw new Error(`Insufficient number of signatures from nodes, required: ${minThresholdRequired}, found: ${validSigs.length}`); + if (!verifierParams.extended_verifier_id && validSigs.length < halfThreshold) { + throw new Error(`Insufficient number of signatures from nodes, required: ${halfThreshold}, found: ${validSigs.length}`); } const validTokens = sessionTokensResolved.filter((token) => { @@ -590,8 +594,8 @@ export async function retrieveOrImportShare(params: { return false; }); - if (!verifierParams.extended_verifier_id && validTokens.length < minThresholdRequired) { - throw new Error(`Insufficient number of session tokens from nodes, required: ${minThresholdRequired}, found: ${validTokens.length}`); + if (!verifierParams.extended_verifier_id && validTokens.length < halfThreshold) { + throw new Error(`Insufficient number of session tokens from nodes, required: ${halfThreshold}, found: ${validTokens.length}`); } sessionTokensResolved.forEach((x, index) => { if (!x || !sessionSigsResolved[index]) sessionTokenData.push(undefined); @@ -616,7 +620,7 @@ export async function retrieveOrImportShare(params: { [] as { index: BN; value: BN }[] ); // run lagrange interpolation on all subsets, faster in the optimistic scenario than berlekamp-welch due to early exit - const allCombis = kCombinations(decryptedShares.length, ~~(endpoints.length / 2) + 1); + const allCombis = kCombinations(decryptedShares.length, halfThreshold); let privateKey: BN | null = null; for (let j = 0; j < allCombis.length; j += 1) { @@ -640,7 +644,7 @@ export async function retrieveOrImportShare(params: { throw new Error("could not derive private key"); } - const thresholdIsNewKey = thresholdSame(isNewKeyResponses, ~~(endpoints.length / 2) + 1); + const thresholdIsNewKey = thresholdSame(isNewKeyResponses, halfThreshold); // Convert each string timestamp to a number const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => Number.parseInt(timestamp, 10)); @@ -716,14 +720,14 @@ export async function retrieveOrImportShare(params: { typeOfUser = "v1"; // for imported keys in legacy networks metadataNonce = await getMetadata(legacyMetadataHost, { pub_key_X: oAuthPubkeyX, pub_key_Y: oAuthPubkeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); finalPubKey = ecCurve.keyFromPrivate(privateKeyWithNonce.toString(16, 64), "hex").getPublic(); } } else { typeOfUser = "v1"; // for imported keys in legacy networks metadataNonce = await getMetadata(legacyMetadataHost, { pub_key_X: oAuthPubkeyX, pub_key_Y: oAuthPubkeyY }); - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); finalPubKey = ecCurve.keyFromPrivate(privateKeyWithNonce.toString(16, 64), "hex").getPublic(); } } else { @@ -755,7 +759,7 @@ export async function retrieveOrImportShare(params: { } if (typeOfUser === "v1" || (typeOfUser === "v2" && metadataNonce.gt(new BN(0)))) { - const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.curve.n); + const privateKeyWithNonce = oAuthKey.add(metadataNonce).umod(ecCurve.n); keyWithNonce = privateKeyWithNonce.toString("hex", 64); } if (keyType === KEY_TYPE.SECP256K1) { diff --git a/src/interfaces.ts b/src/interfaces.ts index 02b8e13..b55a5e8 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -156,11 +156,13 @@ export interface SessionToken { node_puby: string; } export interface TorusPublicKey { + // based on curve type finalKeyData: { walletAddress: string; // format depends on key type X: string; // this is final pub x user before and after updating to 2/n Y: string; // this is final pub y user before and after updating to 2/n }; + // based on curve type oAuthKeyData: { walletAddress: string; // format depends on key type X: string; @@ -185,6 +187,7 @@ export interface TorusKey { oAuthKeyData: TorusPublicKey["oAuthKeyData"] & { privKey: string; }; + // always secp key postboxKeyData: { X: string; Y: string; diff --git a/src/torus.ts b/src/torus.ts index 3e4780a..404410c 100644 --- a/src/torus.ts +++ b/src/torus.ts @@ -193,7 +193,7 @@ class Torus { } } if (this.keyType === KEY_TYPE.ED25519) { - privKeyBuffer = Buffer.from(newPrivateKey, "hex"); + privKeyBuffer = Buffer.from(newPrivateKey.padStart(64, "0"), "hex"); if (privKeyBuffer.length !== 32) { throw new Error("Invalid private key length for given ed25519 key"); }