Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
78 changes: 77 additions & 1 deletion backend/tss_api/src/api/keygen_ed25519/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import { runKeygenCentralizedEd25519 } from "@oko-wallet/teddsa-addon/src/server
import { createPgConn } from "@oko-wallet/postgres-lib";
import { insertKSNode } from "@oko-wallet/oko-pg-interface/ks_nodes";
import { createUser } from "@oko-wallet/oko-pg-interface/oko_users";
import { createWallet } from "@oko-wallet/oko-pg-interface/oko_wallets";
import {
createWallet,
getWalletById,
} from "@oko-wallet/oko-pg-interface/oko_wallets";
import { insertKeyShareNodeMeta } from "@oko-wallet/oko-pg-interface/key_share_node_meta";
import type { WalletStatus } from "@oko-wallet/oko-types/wallets";
import { decryptDataAsync } from "@oko-wallet/crypto-js/node";
import { extractKeyPackageSharesEd25519 } from "@oko-wallet/teddsa-addon/src/server";

import { resetPgDatabase } from "@oko-wallet-tss-api/testing/database";
import { testPgConfig } from "@oko-wallet-tss-api/database/test_config";
Expand Down Expand Up @@ -106,6 +111,12 @@ describe("Ed25519 Keygen", () => {
TEMP_ENC_SECRET,
);

if (!result.success) {
console.error("Keygen failed:", {
code: result.code,
msg: result.msg,
});
}
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.token).toBeDefined();
Expand Down Expand Up @@ -342,5 +353,70 @@ describe("Ed25519 Keygen", () => {
// In production, the user_id would come from the database
}
});

it("should store only signing_share and verifying_share in enc_tss_share", async () => {
await setUpKSNodes(pool);
await setUpKeyShareNodeMeta(pool);

const keygenResult = runKeygenCentralizedEd25519();
const serverKeygenOutput = keygenResult.keygen_outputs[Participant.P1];

// Extract expected shares from server key_package
const expectedShares = extractKeyPackageSharesEd25519(
new Uint8Array(serverKeygenOutput.key_package),
);

const request = generateKeygenRequest(keygenResult);

const result = await runKeygenEd25519(
pool,
TEST_JWT_CONFIG,
request,
TEMP_ENC_SECRET,
);

expect(result.success).toBe(true);
if (result.success) {
// Get wallet from database using wallet_id from result
const getWalletRes = await getWalletById(
pool,
result.data.user.wallet_id,
);
expect(getWalletRes.success).toBe(true);
if (getWalletRes.success && getWalletRes.data) {
const wallet = getWalletRes.data;

// Decrypt enc_tss_share
const encryptedShare = wallet.enc_tss_share.toString("utf-8");
const decryptedShare = await decryptDataAsync(
encryptedShare,
TEMP_ENC_SECRET,
);
const storedShares = JSON.parse(decryptedShare) as {
signing_share: number[];
verifying_share: number[];
};

// Verify structure: should only have signing_share and verifying_share
expect(storedShares).toHaveProperty("signing_share");
expect(storedShares).toHaveProperty("verifying_share");
expect(storedShares).not.toHaveProperty("key_package");
expect(storedShares).not.toHaveProperty("public_key_package");
expect(storedShares).not.toHaveProperty("identifier");

// Verify sizes: each should be 32 bytes
expect(storedShares.signing_share).toHaveLength(32);
expect(storedShares.verifying_share).toHaveLength(32);

// Verify values match expected shares
expect(storedShares.signing_share).toEqual(
expectedShares.signing_share,
);
expect(storedShares.verifying_share).toEqual(
expectedShares.verifying_share,
);
}
}
});
});
});
23 changes: 13 additions & 10 deletions backend/tss_api/src/api/keygen_ed25519/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { getKeyShareNodeMeta } from "@oko-wallet/oko-pg-interface/key_share_node_meta";

import { generateUserToken } from "@oko-wallet-tss-api/api/keplr_auth";
import { extractKeyPackageSharesEd25519 } from "@oko-wallet/teddsa-addon/src/server";

export async function runKeygenEd25519(
db: Pool,
Expand Down Expand Up @@ -114,10 +115,7 @@ export async function runKeygenEd25519(
};
}

// Ed25519 uses 2-of-2 threshold signature with server, not SSS key share
// nodes
// Skip checkKeyShareFromKSNodes validation (which expects secp256k1
// 33-byte keys)
// TODO: Add KS node check after SSS & KSN logic is implemented
const getActiveKSNodesRes = await getActiveKSNodes(db);
if (getActiveKSNodesRes.success === false) {
return {
Expand All @@ -129,14 +127,19 @@ export async function runKeygenEd25519(
const activeKSNodes = getActiveKSNodesRes.data;
const ksNodeIds: string[] = activeKSNodes.map((node) => node.node_id);

const keyPackageJson = JSON.stringify({
key_package: keygen_2.key_package,
public_key_package: keygen_2.public_key_package,
identifier: keygen_2.identifier,
});
// Extract signing_share and verifying_share from key_package
const keyPackageShares = extractKeyPackageSharesEd25519(
new Uint8Array(keygen_2.key_package),
);

// Store only signing_share and verifying_share (64 bytes total)
const sharesData = {
signing_share: keyPackageShares.signing_share,
verifying_share: keyPackageShares.verifying_share,
};

const encryptedShare = await encryptDataAsync(
keyPackageJson,
JSON.stringify(sharesData),
encryptionSecret,
);
const encryptedShareBuffer = Buffer.from(encryptedShare, "utf-8");
Expand Down
116 changes: 0 additions & 116 deletions backend/tss_api/src/api/presign_ed25519/index.ts

This file was deleted.

Loading