Skip to content

Commit

Permalink
feat: tkey store domain
Browse files Browse the repository at this point in the history
  • Loading branch information
guru-web3 committed Feb 20, 2024
1 parent 3d88559 commit 3a2f2af
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 32 deletions.
1 change: 1 addition & 0 deletions packages/common-types/src/baseTypes/aggregateTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ export interface ShareRequestArgs {

export type TkeyStoreItemType = {
id: string;
value?: string;
};

export type ISeedPhraseStore = TkeyStoreItemType & {
Expand Down
31 changes: 20 additions & 11 deletions packages/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {
} from "./lagrangeInterpolatePolynomial";
import Metadata from "./metadata";
// TODO: handle errors for get and set with retries
export const TSS_MODULE = "tssModule";

class ThresholdKey implements ITKey {
modules: ModuleMap;
Expand Down Expand Up @@ -99,6 +100,8 @@ class ThresholdKey implements ITKey {

_shareSerializationMiddleware: ShareSerializationMiddleware;

_accountSalt: string;

storeDeviceShare: (deviceShareStore: ShareStore, customDeviceInfo?: StringifiedType) => Promise<void>;

haveWriteMetadataLock: string;
Expand Down Expand Up @@ -302,7 +305,11 @@ class ThresholdKey implements ITKey {
if (useTSS) {
const { factorEncs, factorPubs, tssPolyCommits } = await this._initializeNewTSSKey(this.tssTag, deviceTSSShare, factorPub, deviceTSSIndex);
const accountSalt = generateSalt();
this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs, accountSalt });
this._setTKeyStoreItem(TSS_MODULE, {
id: "accountSalt",
value: accountSalt,
});
this.metadata.addTSSData({ tssTag: this.tssTag, tssNonce: 0, tssPolyCommits, factorPubs, factorEncs });
}
return this.getKeyDetails();
}
Expand Down Expand Up @@ -420,7 +427,7 @@ class ThresholdKey implements ITKey {
}
if (tssSharePub.getX().cmp(_tssSharePub.getX()) === 0 && tssSharePub.getY().cmp(_tssSharePub.getY()) === 0) {
if (accountIndex && accountIndex > 0) {
const nonce = this.computeAccountNonce(accountIndex);
const nonce = await this.computeAccountNonce(accountIndex);
const derivedShare = userDec.add(nonce).umod(ecCurve.n);
return { tssIndex, tssShare: derivedShare };
}
Expand Down Expand Up @@ -453,7 +460,7 @@ class ThresholdKey implements ITKey {
}
if (tssSharePub.getX().cmp(_tssSharePub.getX()) === 0 && tssSharePub.getY().cmp(_tssSharePub.getY()) === 0) {
if (accountIndex && accountIndex > 0) {
const nonce = this.computeAccountNonce(accountIndex);
const nonce = await this.computeAccountNonce(accountIndex);
const derivedShare = tssShare.add(nonce).umod(ecCurve.n);
return { tssIndex, tssShare: derivedShare };
}
Expand All @@ -472,10 +479,10 @@ class ThresholdKey implements ITKey {
return tssPolyCommits;
}

getTSSPub(accountIndex?: number): Point {
async getTSSPub(accountIndex?: number): Promise<Point> {
const tssCommits = this.getTSSCommits();
if (accountIndex && accountIndex > 0) {
const nonce = this.computeAccountNonce(accountIndex);
const nonce = await this.computeAccountNonce(accountIndex);
// we need to add the pub key nonce to the tssPub
const noncePub = ecCurve.keyFromPrivate(nonce.toString("hex")).getPublic();
const pubKeyPoint = ecCurve.keyFromPublic({ x: tssCommits[0].x.toString("hex"), y: tssCommits[0].y.toString("hex") }).getPublic();
Expand Down Expand Up @@ -897,14 +904,16 @@ class ThresholdKey implements ITKey {
};
}
const accountSalt = generateSalt();

this.metadata.addTSSData({
tssTag: this.tssTag,
tssNonce: newTssNonce,
tssPolyCommits: newTSSCommits,
factorPubs,
factorEncs,
accountSalt,
});
this._setTKeyStoreItem(TSS_MODULE, {
id: "accountSalt",
value: accountSalt,
});
await this._syncShareMetadata();
} catch (error) {
Expand Down Expand Up @@ -1992,13 +2001,13 @@ class ThresholdKey implements ITKey {
return Promise.all(Object.keys(this.modules).map((x) => this.modules[x].initialize()));
}

private computeAccountNonce(index: number) {
private async computeAccountNonce(index: number) {
// generation should occur during tkey.init, fails if accountSalt is absent
const { accountSalt } = this.metadata;
if (!accountSalt) {
this._accountSalt = this._accountSalt || (await this.getTKeyStoreItem(TSS_MODULE, "accountSalt")).value;
if (!this._accountSalt) {
throw CoreError.accountSaltUndefined();
}
const accountHash = keccak256(Buffer.from(`${index}${accountSalt}`)).slice(2);
const accountHash = keccak256(Buffer.from(`${index}${this._accountSalt}`)).slice(2);
return index && index > 0 ? new BN(accountHash, "hex").umod(ecCurve.curve.n) : new BN(0);
}
}
Expand Down
13 changes: 2 additions & 11 deletions packages/core/src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ class Metadata implements IMetadata {
};
};

// salt
accountSalt?: string;

constructor(input: Point) {
this.tssPolyCommits = {};
this.tssNonces = {};
Expand All @@ -87,7 +84,7 @@ class Metadata implements IMetadata {
}

static fromJSON(value: StringifiedType): Metadata {
const { pubKey, polyIDList, generalStore, tkeyStore, scopedStore, nonce, tssNonces, tssPolyCommits, factorPubs, factorEncs, accountSalt } = value;
const { pubKey, polyIDList, generalStore, tkeyStore, scopedStore, nonce, tssNonces, tssPolyCommits, factorPubs, factorEncs } = value;
const point = Point.fromCompressedPub(pubKey);
const metadata = new Metadata(point);
const unserializedPolyIDList: PolyIDAndShares[] = [];
Expand All @@ -96,7 +93,6 @@ class Metadata implements IMetadata {
if (tkeyStore) metadata.tkeyStore = tkeyStore;
if (scopedStore) metadata.scopedStore = scopedStore;
if (nonce) metadata.nonce = nonce;
if (accountSalt) metadata.accountSalt = accountSalt;
if (tssPolyCommits) {
metadata.tssPolyCommits = {};
for (const key in tssPolyCommits) {
Expand Down Expand Up @@ -194,16 +190,12 @@ class Metadata implements IMetadata {
factorEncs?: {
[factorPubID: string]: FactorEnc;
};
accountSalt?: string;
}): void {
const { tssTag, tssNonce, tssPolyCommits, factorPubs, factorEncs, accountSalt } = tssData;
const { tssTag, tssNonce, tssPolyCommits, factorPubs, factorEncs } = tssData;
if (tssNonce !== undefined) this.tssNonces[tssTag] = tssNonce;
if (tssPolyCommits) this.tssPolyCommits[tssTag] = tssPolyCommits;
if (factorPubs) this.factorPubs[tssTag] = factorPubs;
if (factorEncs) this.factorEncs[tssTag] = factorEncs;
if (accountSalt && !this.accountSalt) {
this.accountSalt = accountSalt;
}
}

// appends shares and public polynomial to metadata.
Expand Down Expand Up @@ -347,7 +339,6 @@ class Metadata implements IMetadata {
...(this.tssPolyCommits && { tssPolyCommits: this.tssPolyCommits }),
...(this.factorPubs && { factorPubs: this.factorPubs }),
...(this.factorEncs && { factorEncs: this.factorEncs }),
...(this.accountSalt && { accountSalt: this.accountSalt }),
};
}
}
Expand Down
20 changes: 10 additions & 10 deletions packages/default/test/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
}
const { tssShare: retrievedTSS1, tssIndex: retrievedTSSIndex1 } = await tb1.getTSSShare(factorKey, { accountIndex: 1 });
const tssPrivKey1 = getLagrangeCoeffs([1, retrievedTSSIndex1], 1)
.mul(serverDKGPrivKeys[0].add(tb1.computeAccountNonce(1)))
.mul(serverDKGPrivKeys[0].add(await tb1.computeAccountNonce(1)))
.add(getLagrangeCoeffs([1, retrievedTSSIndex1], retrievedTSSIndex1).mul(retrievedTSS1))
.umod(ecCurve.n);
const tssPubKey1 = ecCurve.keyFromPrivate(tssPrivKey1).getPublic();

const pubKey1 = tb1.getTSSPub(1);
const pubKey1 = await tb1.getTSSPub(1);
strictEqual(tssPubKey1.x.toString(16, 64), pubKey1.x.toString(16, 64));
strictEqual(tssPubKey1.y.toString(16, 64), pubKey1.y.toString(16, 64));

Expand All @@ -141,12 +141,12 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {

const { tssShare: retrievedTSS2, tssIndex: retrievedTSSIndex2 } = await tb2.getTSSShare(factorKey, { accountIndex: 2 });
const tssPrivKey2 = getLagrangeCoeffs([1, retrievedTSSIndex2], 1)
.mul(serverDKGPrivKeys[0].add(tb1.computeAccountNonce(2)))
.mul(serverDKGPrivKeys[0].add(await tb1.computeAccountNonce(2)))
.add(getLagrangeCoeffs([1, retrievedTSSIndex2], retrievedTSSIndex2).mul(retrievedTSS2))
.umod(ecCurve.n);

const tssPubKey2 = getPubKeyPoint(tssPrivKey2);
const pubKey2 = tb1.getTSSPub(2);
const pubKey2 = await tb1.getTSSPub(2);

strictEqual(tssPubKey2.x.toString(16, 64), pubKey2.x.toString(16, 64));
strictEqual(tssPubKey2.y.toString(16, 64), pubKey2.y.toString(16, 64));
Expand Down Expand Up @@ -174,15 +174,15 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
const tssSharePub = ecCurve.keyFromPrivate(retrievedTSS.toString("hex")).getPublic();
const { tssShare: retrievedTSS2 } = await tb2.getTSSShare(factorKey, { accountIndex: 1 });
const tssSharePub2 = ecCurve.keyFromPrivate(retrievedTSS2.toString("hex")).getPublic();
const nonce = tb1.computeAccountNonce(1);
const nonce = await tb1.computeAccountNonce(1);
const noncePub = ecCurve.keyFromPrivate(nonce.toString("hex")).getPublic();
const tssShareDerived = tssSharePub.add(noncePub);
strictEqual(tssShareDerived.getX().toString("hex"), tssSharePub2.getX().toString("hex"));
strictEqual(tssShareDerived.getY().toString("hex"), tssSharePub2.getY().toString("hex"));

const { tssShare: retrievedTSS3 } = await tb2.getTSSShare(factorKey, { accountIndex: 2 });
const tssSharePub3 = ecCurve.keyFromPrivate(retrievedTSS3.toString("hex")).getPublic();
const nonce2 = tb1.computeAccountNonce(2);
const nonce2 = await tb1.computeAccountNonce(2);
const noncePub2 = ecCurve.keyFromPrivate(nonce2.toString("hex")).getPublic();
const tssShareDerived2 = tssSharePub.add(noncePub2);
strictEqual(tssShareDerived2.getX().toString("hex"), tssSharePub3.getX().toString("hex"));
Expand All @@ -192,7 +192,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
{
const { tssShare: newTSS, tssIndex } = await tb1.getTSSShare(factorKey, { accountIndex: 1 });
const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1)
.mul(new BN(serverDKGPrivKeys[1], "hex").add(tb1.computeAccountNonce(1)))
.mul(new BN(serverDKGPrivKeys[1], "hex").add(await tb1.computeAccountNonce(1)))
.add(getLagrangeCoeffs([1, 2], 2).mul(newTSS))
.umod(ecCurve.n);
strictEqual(tssPrivKey1.toString(16, 64), newTSSPrivKey.toString(16, 64));
Expand All @@ -203,7 +203,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
{
const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey2, { accountIndex: 1 });
const newTSSPrivKey = getLagrangeCoeffs([1, 3], 1)
.mul(new BN(serverDKGPrivKeys[1], "hex").add(tb1.computeAccountNonce(1)))
.mul(new BN(serverDKGPrivKeys[1], "hex").add(await tb1.computeAccountNonce(1)))
.add(getLagrangeCoeffs([1, 3], 3).mul(newTSS2))
.umod(ecCurve.n);
strictEqual(tssPrivKey1.toString(16, 64), newTSSPrivKey.toString(16, 64));
Expand All @@ -214,7 +214,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
{
const { tssShare: newTSS, tssIndex } = await tb2.getTSSShare(factorKey, { accountIndex: 2 });
const newTSSPrivKey = getLagrangeCoeffs([1, 2], 1)
.mul(new BN(serverDKGPrivKeys[1], "hex").add(tb2.computeAccountNonce(2)))
.mul(new BN(serverDKGPrivKeys[1], "hex").add(await tb2.computeAccountNonce(2)))
.add(getLagrangeCoeffs([1, 2], 2).mul(newTSS))
.umod(ecCurve.n);
strictEqual(tssPrivKey2.toString(16, 64), newTSSPrivKey.toString(16, 64));
Expand All @@ -225,7 +225,7 @@ export const sharedTestCases = (mode, torusSP, storageLayer) => {
{
const { tssShare: newTSS2, tssIndex } = await tb2.getTSSShare(factorKey2, { accountIndex: 2 });
const newTSSPrivKey = getLagrangeCoeffs([1, 3], 1)
.mul(new BN(serverDKGPrivKeys[1], "hex").add(tb1.computeAccountNonce(2)))
.mul(new BN(serverDKGPrivKeys[1], "hex").add(await tb1.computeAccountNonce(2)))
.add(getLagrangeCoeffs([1, 3], 3).mul(newTSS2))
.umod(ecCurve.n);
strictEqual(tssPrivKey2.toString(16, 64), newTSSPrivKey.toString(16, 64));
Expand Down

0 comments on commit 3a2f2af

Please sign in to comment.