Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
71b343f
feat: move tss to different file
ieow May 9, 2023
15fe174
feat: update
ieow May 10, 2023
619a51e
feat: update with mock rss
ieow May 10, 2023
7340911
feat: most tests pass with mock rss
ieow May 10, 2023
773b4d2
feat: tests pass with mock rss
ieow May 10, 2023
c4fb54c
fix: using verifierID
ieow May 15, 2023
4139395
fix: tss tests
ieow May 15, 2023
d8a2522
fix: package.json, before test
ieow May 18, 2023
3ef089e
fix: remove test
ieow May 18, 2023
9874351
Merge branch 'v2' into feat/v2-tss-test
ieow May 19, 2023
c142a3d
fix: remove redundant tests
ieow May 19, 2023
fb93e1b
fix: updated
metallicalfa2 Jun 19, 2023
3fcfde4
fix: updated
metallicalfa2 Jun 19, 2023
b9d5c4c
feat: initial commit tssModule
ieow May 11, 2023
a89c1ff
feat: example test using tss module
ieow May 11, 2023
663aa64
feat: remove unused test
ieow May 11, 2023
515044d
fix: tss modulfied serialize, deserialized
ieow May 15, 2023
ab7428c
fix: add comment
ieow May 15, 2023
6e40bc2
fix: merge fix
ieow Jun 5, 2023
0b43520
fix: update package.json
ieow Jun 5, 2023
b9d8406
fix: tss tests
ieow Jun 6, 2023
d9f46c3
fix: update tss module readme
ieow Jun 6, 2023
452e432
fix: rebase
ieow Jun 20, 2023
2c81470
feat: modify module usage pattern - security question
ieow May 17, 2023
d8ce819
feat: modify module utils pattern - security question
ieow May 17, 2023
edf9fe5
feat: refactor remaining modules
ieow May 18, 2023
4be789c
fix: menmonic module and share transfer module
ieow May 18, 2023
c2d0b81
feat: add getTkeyStatus
ieow May 18, 2023
0d78676
fix: shareTransfer module test
ieow Jun 22, 2023
2435f39
fix: bug syncShareMetadata did not sync
ieow Jun 23, 2023
809ed3e
fix: add back missing tests
ieow Jun 23, 2023
f9b1314
feat: no need refresh trf pointer on delete share
ieow Jun 23, 2023
1d1e3c5
fix: add delete share test case for shr trf
ieow Jun 23, 2023
d544d20
feat: torus service provider with multiple tag mpc key
ieow Jun 27, 2023
f7f5523
fix: rss mock server issue
ieow Jun 27, 2023
0e597de
fix: failing tss tests
ieow Jun 27, 2023
de3c43a
fix: api improvement
ieow Jun 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24,678 changes: 2,482 additions & 22,196 deletions package-lock.json

Large diffs are not rendered by default.

37 changes: 34 additions & 3 deletions packages/common-types/src/baseTypes/aggregateTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export type RefreshMiddlewareMap = {
};

export type ReconstructKeyMiddlewareMap = {
[moduleName: string]: () => Promise<BN[]>;
// eslint-disable-next-line no-use-before-define
[moduleName: string]: (tkey: ITKeyApi) => Promise<BN[]>;
};

export type ShareSerializationMiddleware = {
Expand Down Expand Up @@ -78,6 +79,24 @@ export interface IMetadata extends ISerializable {

nonce: number;

tssNonces?: {
[tssTag: string]: number;
};

tssPolyCommits?: {
[tssTag: string]: Point[];
};

factorPubs?: {
[tssTag: string]: Point[];
};

factorEncs?: {
[tssTag: string]: {
[factorPubID: string]: FactorEnc;
};
};

getShareIndexesForPolynomial(polyID: PolynomialID): string[];
getLatestPublicPolynomial(): PublicPolynomial;
addTSSData(tssData: {
Expand Down Expand Up @@ -142,6 +161,8 @@ export type KeyDetails = {
threshold: number;
totalShares: number;
shareDescriptions: ShareDescriptionMap;
deviceShare?: ShareStore;
userShare?: ShareStore;
};

export type TKeyArgs = {
Expand Down Expand Up @@ -252,8 +273,18 @@ export type LocalMetadataTransitions = [LocalTransitionShares, LocalTransitionDa

export interface ITKeyApi {
getMetadata(): IMetadata;
getServiceProvider(): IServiceProvider;
getStorageLayer(): IStorageLayer;
initialize(params: { input?: ShareStore; importKey?: BN; neverInitializeNewKey?: boolean }): Promise<KeyDetails>;
initialize(params: {
withShare?: ShareStore;
importKey?: BN;
neverInitializeNewKey?: boolean;
transitionMetadata?: IMetadata;
previouslyFetchedCloudMetadata?: IMetadata;
previousLocalMetadataTransitions?: LocalMetadataTransitions;
delete1OutOf1?: boolean;
// input?: ShareStore; importKey?: BN; neverInitializeNewKey?: boolean
}): Promise<KeyDetails>;
catchupToLatestShare(params: {
shareStore: ShareStore;
polyID?: string;
Expand All @@ -267,7 +298,7 @@ export interface ITKeyApi {
moduleName: string,
middleware: (generalStore: unknown, oldShareStores: ShareStoreMap, newShareStores: ShareStoreMap) => unknown
): void;
_addReconstructKeyMiddleware(moduleName: string, middleware: () => Promise<Array<BN>>): void;
_addReconstructKeyMiddleware(moduleName: string, middleware: (tkey: ITKeyApi) => Promise<Array<BN>>): void;
_addShareSerializationMiddleware(
serialize: (share: BN, type: string) => Promise<unknown>,
deserialize: (serializedShare: unknown, type: string) => Promise<BN>
Expand Down
8 changes: 8 additions & 0 deletions packages/common-types/src/baseTypes/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ export interface TorusServiceProviderArgs extends ServiceProviderArgs {
nodePubKeys?: PointHex[];
}

export enum TkeyStatus {
NOT_INITIALIZED = "NOT_INITIALIZED",
// READ MODE
INITIALIZED = "INITIALIZED",
// WRITE MODE
RECONSTRUCTED = "RECONSTRUCTED",
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type StringifiedType = Record<string, any>;

Expand Down
67 changes: 61 additions & 6 deletions packages/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
ShareStorePolyIDShareIndexMap,
StringifiedType,
TKeyArgs,
TkeyStatus,
TkeyStoreItemType,
toPrivKeyECC,
} from "@tkey/common-types";
Expand Down Expand Up @@ -220,6 +221,23 @@ class ThresholdKey implements ITKey {
throw CoreError.metadataUndefined();
}

getServiceProvider(): IServiceProvider {
if (typeof this.serviceProvider !== "undefined") {
return this.serviceProvider;
}

throw CoreError.default("serviceProvider undefined");
}

getTkeyStatus(): TkeyStatus {
// NOT INITIALIZED
if (!this.metadata) return TkeyStatus.NOT_INITIALIZED;
// READ MODE
if (!this.privKey) return TkeyStatus.INITIALIZED;
// WRITE MODE
return TkeyStatus.RECONSTRUCTED;
}

async initialize(params?: {
withShare?: ShareStore;
importKey?: BN;
Expand All @@ -232,7 +250,7 @@ class ThresholdKey implements ITKey {
deviceTSSShare?: BN;
deviceTSSIndex?: number;
factorPub?: Point;
}): Promise<KeyDetails> {
}): Promise<KeyDetails & { deviceShare?: ShareStore; userShare?: ShareStore }> {
// setup initial params/states
const p = params || {};

Expand Down Expand Up @@ -287,7 +305,7 @@ class ThresholdKey implements ITKey {
throw CoreError.default("key has not been generated yet");
}
// no metadata set, assumes new user
await this._initializeNewKey({
const result = await this._initializeNewKey({
initializeModules: true,
importedKey: importKey,
delete1OutOf1: p.delete1OutOf1,
Expand All @@ -296,14 +314,47 @@ class ThresholdKey implements ITKey {
const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub, deviceTSSIndex);
this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs });
}
return this.getKeyDetails();
const keyDetail = this.getKeyDetails();
keyDetail.deviceShare = result.deviceShare;
keyDetail.userShare = result.userShare;

return keyDetail;
}
// else we continue with catching up share and metadata
shareStore = ShareStore.fromJSON(rawServiceProviderShare);
} else {
throw CoreError.default("Input is not supported");
}

return this.initializeWithShareStore({
shareStore,
transitionMetadata,
previouslyFetchedCloudMetadata,
previousLocalMetadataTransitions,
useTSS,
deviceTSSShare,
factorPub,
});
}

async initializeWithShareStore(params: {
shareStore: ShareStore;
transitionMetadata?: Metadata;
previouslyFetchedCloudMetadata?: Metadata;
previousLocalMetadataTransitions?: LocalMetadataTransitions;
useTSS?: boolean;
deviceTSSShare?: BN;
factorPub?: Point;
}) {
const { shareStore, transitionMetadata, previouslyFetchedCloudMetadata, previousLocalMetadataTransitions, useTSS, deviceTSSShare, factorPub } =
params;

const previousLocalMetadataTransitionsExists =
previousLocalMetadataTransitions && previousLocalMetadataTransitions[0].length > 0 && previousLocalMetadataTransitions[1].length > 0;
const reinitializing = transitionMetadata && previousLocalMetadataTransitionsExists; // are we reinitializing the SDK?
// in the case we're reinitializing whilst newKeyAssign has not been synced
const reinitializingWithNewKeyAssign = reinitializing && previouslyFetchedCloudMetadata === undefined;

// We determine the latest metadata on the SDK and if there has been
// needed transitions to include
let currentMetadata: Metadata;
Expand Down Expand Up @@ -354,7 +405,9 @@ class ThresholdKey implements ITKey {
if (useTSS) {
if (!this.metadata.tssPolyCommits[this.tssTag]) {
// if tss shares have not been created for this tssTag, create new tss sharing
await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub);
const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub);
this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs });
this._syncShareMetadata();
}
}

Expand Down Expand Up @@ -578,7 +631,7 @@ class ThresholdKey implements ITKey {
await Promise.all(
Object.keys(this._reconstructKeyMiddleware).map(async (x) => {
if (Object.prototype.hasOwnProperty.call(this._reconstructKeyMiddleware, x)) {
const extraKeys = await this._reconstructKeyMiddleware[x]();
const extraKeys = await this._reconstructKeyMiddleware[x](this);
returnObject[x] = extraKeys;
returnObject.allKeys.push(...extraKeys);
}
Expand Down Expand Up @@ -1434,6 +1487,7 @@ class ThresholdKey implements ITKey {

const shareArray = this.getAllShareStoresForLatestPolynomial().map((x) => x.share.share);
await this.syncMultipleShareMetadata(shareArray, adjustScopedStore);
if (!this.manualSync) this.syncLocalMetadataTransitions();
}

async syncMultipleShareMetadata(shares: BN[], adjustScopedStore?: (ss: unknown) => unknown): Promise<void> {
Expand Down Expand Up @@ -1471,7 +1525,7 @@ class ThresholdKey implements ITKey {
this._refreshMiddleware[moduleName] = middleware;
}

_addReconstructKeyMiddleware(moduleName: string, middleware: () => Promise<BN[]>): void {
_addReconstructKeyMiddleware(moduleName: string, middleware: (tkey: ITKeyApi) => Promise<BN[]>): void {
this._reconstructKeyMiddleware[moduleName] = middleware;
}

Expand Down Expand Up @@ -1697,6 +1751,7 @@ class ThresholdKey implements ITKey {
getApi(): ITKeyApi {
return {
getMetadata: this.getMetadata.bind(this),
getServiceProvider: this.getServiceProvider.bind(this),
getStorageLayer: this.getStorageLayer.bind(this),
initialize: this.initialize.bind(this),
catchupToLatestShare: this.catchupToLatestShare.bind(this),
Expand Down
4 changes: 3 additions & 1 deletion packages/default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@
"@tkey/share-serialization": "^8.1.0-alpha.0",
"@tkey/share-transfer": "^8.1.0-alpha.0",
"@tkey/storage-layer-torus": "^8.1.0-alpha.0",
"@tkey/mnemonic": "^8.1.0-alpha.0",
"@toruslabs/eccrypto": "^2.1.1",
"@toruslabs/rss-client": "^1.4.1",
"bn.js": "^5.2.1"
},
"devDependencies": {
"@tkey/private-keys": "^8.1.0-alpha.0",
"@tkey/seed-phrase": "^8.1.0-alpha.0",
"@toruslabs/http-helpers": "^4.0.0",
"@toruslabs/rss-client": "^1.4.1",
"@tkey/tss": "^8.1.0-alpha.0",
"jsrsasign": "^10.6.1",
"web3-utils": "^1.8.1"
},
Expand Down
60 changes: 57 additions & 3 deletions packages/default/test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,16 @@ export function getServiceProvider(params) {
return new ServiceProviderBase({ postboxKey: isEmptyProvider ? null : PRIVATE_KEY });
}

const MockServers = [new MockServer(), new MockServer(), new MockServer(), new MockServer(), new MockServer()];

export async function setupTSSMocks(opts) {
let { serviceProvider, verifierName, verifierId, maxTSSNonceToSimulate, tssTag } = opts;
let { serviceProvider, verifierName, verifierId, maxTSSNonceToSimulate, tssTag, postboxKey } = opts;
tssTag = tssTag || "default";
serviceProvider._setVerifierNameVerifierId(verifierName, verifierId);
const vid = serviceProvider.getVerifierNameVerifierId();
maxTSSNonceToSimulate = maxTSSNonceToSimulate || 1;
const serverEndpoints = [new MockServer(), new MockServer(), new MockServer(), new MockServer(), new MockServer()];
// const serverEndpoints = [new MockServer(), new MockServer(), new MockServer(), new MockServer(), new MockServer()];
const serverEndpoints = MockServers;
const serverCount = serverEndpoints.length;
const serverPrivKeys = [];
for (let i = 0; i < serverCount; i++) {
Expand Down Expand Up @@ -92,10 +95,17 @@ export async function setupTSSMocks(opts) {
});
})
);
serviceProvider._setTSSPubKey("default", j, new Point(dkg2Pub.x, dkg2Pub.y));
serviceProvider._setTSSPubKey(tssTag, j, new Point(dkg2Pub.x, dkg2Pub.y));
}

serviceProvider._setTSSNodeDetails(serverEndpoints, serverPubKeys, serverThreshold);
serviceProvider.rssNodeDetails = { ...serviceProvider.tssNodeDetails };

// update new serviceprovider postbox key
if (!postboxKey) {
const postboxKeyGenerated = new BN(generatePrivate());
serviceProvider.postboxKey = postboxKeyGenerated.toString(16, 64);
}

return {
serverEndpoints,
Expand Down Expand Up @@ -182,3 +192,47 @@ export async function assignTssDkgKeys(opts) {
// serverDKGPubKeys,
};
}

export async function setupTSS(opts) {
const { serviceProvider, verifierName, verifierId, maxTSSNonceToSimulate, tssTag, MOCK_RSS, postboxKey } = opts;
if (MOCK_RSS) {
const { serverEndpoints, serverPubKeys, serverDKGPrivKeys, serverDKGPubKeys } = await setupTSSMocks({
serviceProvider,
verifierName,
verifierId,
maxTSSNonceToSimulate,
tssTag,
postboxKey,
});
const signatures = "signature";
return {
signatures,
serverDKGPrivKeys,
};
}

// get signature and postboxkey from nodes
const { signatures, postboxkey } = await fetchPostboxKeyAndSigs({
serviceProvider,
verifierName,
verifierId,
});
serviceProvider.postboxKey = postboxkey;
const { serverDKGPrivKeys } = await assignTssDkgKeys({
serviceProvider,
verifierName,
verifierId,
maxTSSNonceToSimulate,
tssTag,
});

return {
signatures,
serverDKGPrivKeys,
};
}

export const generateVerifierId = (prefix = "") => {
const randomkey = generatePrivate().toString("hex");
return `${prefix}${randomkey}@mail.com`;
};
Loading