Skip to content

Commit

Permalink
fix median function
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshu committed Mar 5, 2024
1 parent b34dd1e commit a7d1ecd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
20 changes: 20 additions & 0 deletions src/helpers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,23 @@ export function encParamsHexToBuf(eciesData: Omit<EciesHex, "ciphertext">): Omit
mac: Buffer.from(eciesData.mac, "hex"),
};
}

export function calculateMedian(arr: number[]): number {
const arrSize = arr.length;

if (arrSize === 0) return 0;
const sortedArr = arr.sort(function (a, b) {
return a - b;
});

// odd length
if (arrSize % 2 !== 0) {
return sortedArr[Math.floor(arrSize / 2)];
}

// return average of two mid values in case of even arrSize
const mid1 = sortedArr[arrSize / 2 - 1];

const mid2 = sortedArr[arrSize / 2];
return (mid1 + mid2) / 2;
}
16 changes: 8 additions & 8 deletions src/helpers/nodeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
} from "../interfaces";
import log from "../loglevel";
import { Some } from "../some";
import { kCombinations, normalizeKeysResult, normalizeLegacyKeysResult, thresholdSame } from "./common";
import { calculateMedian, kCombinations, normalizeKeysResult, normalizeLegacyKeysResult, thresholdSame } from "./common";
import { generateAddressFromPrivKey, generateAddressFromPubKey, keccak256 } from "./keyUtils";
import { lagrangeInterpolation } from "./langrangeInterpolatePoly";
import { decryptNodeData, getMetadata, getOrSetNonce } from "./metadataUtils";
Expand Down Expand Up @@ -104,16 +104,16 @@ export const GetPubKeyOrKeyAssign = async (params: {
// push only those indexes for nodes who are returning pub key matching with threshold pub key.
// this check is important when different nodes have different keys assigned to a user.
if (currentNodePubKey === thresholdPubKey) {
const nodeIndex = parseInt(x1.result.node_index);
const nodeIndex = Number.parseInt(x1.result.node_index);
if (nodeIndex) nodeIndexes.push(nodeIndex);
}
const serverTimeOffset = x1.result.server_time_offset ? parseInt(x1.result.server_time_offset, 10) : 0;
const serverTimeOffset = x1.result.server_time_offset ? Number.parseInt(x1.result.server_time_offset, 10) : 0;
serverTimeOffsets.push(serverTimeOffset);
}
});
}

const serverTimeOffset = Math.max(...serverTimeOffsets);
const serverTimeOffset = keyResult ? calculateMedian(serverTimeOffsets) : 0;
return Promise.resolve({ keyResult, serverTimeOffset, nodeIndexes, errorResult, nonceResult });
}
return Promise.reject(
Expand Down Expand Up @@ -532,14 +532,14 @@ export async function retrieveOrImportShare(params: {
const thresholdIsNewKey = thresholdSame(isNewKeyResponses, ~~(endpoints.length / 2) + 1);

// Convert each string timestamp to a number
const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => parseInt(timestamp, 10));
const serverOffsetTimes = serverTimeOffsetResponses.map((timestamp) => Number.parseInt(timestamp, 10));
return {
privateKey,
sessionTokenData,
thresholdNonceData,
nodeIndexes,
isNewKey: thresholdIsNewKey === "true",
serverTimeOffsetResponse: serverTimeOffset || Math.max(...serverOffsetTimes),
serverTimeOffsetResponse: serverTimeOffset || calculateMedian(serverOffsetTimes),
};
}
throw new Error("Invalid");
Expand Down Expand Up @@ -685,14 +685,14 @@ export const legacyKeyLookup = async (endpoints: string[], verifier: string, ver
lookupResults.forEach((x1) => {
if (x1 && x1.result) {
const timeOffSet = x1.result.server_time_offset;
const serverTimeOffset = timeOffSet ? parseInt(timeOffSet, 10) : 0;
const serverTimeOffset = timeOffSet ? Number.parseInt(timeOffSet, 10) : 0;
serverTimeOffsets.push(serverTimeOffset);
}
});
}

const serverTimeOffset = Math.max(...serverTimeOffsets);
if (keyResult || errorResult) {
const serverTimeOffset = keyResult ? calculateMedian(serverTimeOffsets) : 0;
return Promise.resolve({ keyResult, errorResult, serverTimeOffset });
}
return Promise.reject(new Error(`invalid results ${JSON.stringify(lookupResults)}`));
Expand Down
5 changes: 3 additions & 2 deletions src/torus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import stringify from "json-stable-stringify";

import { config } from "./config";
import {
calculateMedian,
encParamsBufToHex,
generateAddressFromPrivKey,
generateAddressFromPubKey,
Expand Down Expand Up @@ -404,7 +405,7 @@ class Torus {
for (let i = 0; i < shareResponses.length; i += 1) {
const currentShareResponse = shareResponses[i] as JRPCResponse<LegacyShareRequestResult>;
const timeOffSet = currentShareResponse?.result?.server_time_offset;
const parsedTimeOffset = timeOffSet ? parseInt(timeOffSet, 10) : 0;
const parsedTimeOffset = timeOffSet ? Number.parseInt(timeOffSet, 10) : 0;
serverTimeOffsets.push(parsedTimeOffset);
if (currentShareResponse?.result?.keys?.length > 0) {
currentShareResponse.result.keys.sort((a, b) => new BN(a.Index, 16).cmp(new BN(b.Index, 16)));
Expand Down Expand Up @@ -464,7 +465,7 @@ class Torus {
if (privateKey === undefined || privateKey === null) {
throw new Error("could not derive private key");
}
return { privateKey, serverTimeOffset: this.serverTimeOffset || Math.max(...serverTimeOffsets) };
return { privateKey, serverTimeOffset: this.serverTimeOffset || calculateMedian(serverTimeOffsets) };
}
throw new Error("invalid");
});
Expand Down

0 comments on commit a7d1ecd

Please sign in to comment.