From b4ae6fa8732c46cf9da1235c8d185e2ffb690fb7 Mon Sep 17 00:00:00 2001 From: Elden Park Date: Mon, 12 Jan 2026 19:19:42 -0800 Subject: [PATCH] Revert "crypto/teddsa: compute "verifying keyshare" from "signing share"" This reverts commit a50f08efac61cba28d4884d9ebed579e7204177f. --- common/oko_types/src/user_key_share/index.ts | 102 +---- .../tests/integration_tests.rs | 150 ------ .../wasm/src/keys/mod.rs | 2 - .../wasm/src/keys/scalar_mult.rs | 78 ---- embed/oko_attached/src/crypto/scalar.ts | 35 -- embed/oko_attached/src/crypto/sss_ed25519.ts | 428 ++++++++++-------- internals/ci/src/cmds/build_frost.ts | 13 +- key_share_node/ksn_interface/src/key_share.ts | 21 - 8 files changed, 249 insertions(+), 580 deletions(-) delete mode 100644 crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/scalar_mult.rs delete mode 100644 embed/oko_attached/src/crypto/scalar.ts diff --git a/common/oko_types/src/user_key_share/index.ts b/common/oko_types/src/user_key_share/index.ts index 4e08e3e4f..eae42744d 100644 --- a/common/oko_types/src/user_key_share/index.ts +++ b/common/oko_types/src/user_key_share/index.ts @@ -1,4 +1,4 @@ -import { Bytes, type Bytes32, type Bytes64 } from "@oko-wallet/bytes"; +import type { Bytes32 } from "@oko-wallet/bytes"; export interface RunExpandSharesResult { t: number; @@ -24,103 +24,3 @@ export interface PointNumArr { x: number[]; y: number[]; } - -/** - * TEDDSA key share for KS Node storage. - * - * identifier: 32 bytes - SSS x-coordinate (node_name SHA256, byte[31] &= 0x0F) - * signing_share: 32 bytes - SSS y-coordinate (split signing share) - * - * Note: verifying_share is NOT stored. - * It can be recovered from signing_share via scalar_base_mult(). - * - * Total: 64 bytes (same size as Point256) - */ -export interface TeddsaKeyShare { - identifier: Bytes32; - signing_share: Bytes32; -} - -export interface TeddsaKeyShareByNode { - node: NodeNameAndEndpoint; - share: TeddsaKeyShare; -} - -/** - * Serialize TeddsaKeyShare to Bytes64. - * Format: identifier (32 bytes) || signing_share (32 bytes) - */ -export function teddsaKeyShareToBytes64(share: TeddsaKeyShare): Bytes64 { - const combined = new Uint8Array(64); - combined.set(share.identifier.toUint8Array(), 0); - combined.set(share.signing_share.toUint8Array(), 32); - - const result = Bytes.fromUint8Array(combined, 64); - if (!result.success) { - throw new Error(`Failed to create Bytes64: ${result.err}`); - } - return result.data; -} - -/** - * Deserialize Bytes64 to TeddsaKeyShare. - */ -export function bytes64ToTeddsaKeyShare(bytes: Bytes64): TeddsaKeyShare { - const arr = bytes.toUint8Array(); - - const identifierResult = Bytes.fromUint8Array(arr.slice(0, 32), 32); - if (!identifierResult.success) { - throw new Error(`Failed to extract identifier: ${identifierResult.err}`); - } - - const signingResult = Bytes.fromUint8Array(arr.slice(32, 64), 32); - if (!signingResult.success) { - throw new Error(`Failed to extract signing_share: ${signingResult.err}`); - } - - return { - identifier: identifierResult.data, - signing_share: signingResult.data, - }; -} - -/** - * Convert TeddsaKeyShare to 128-char hex string (for KS node API). - */ -export function teddsaKeyShareToHex(share: TeddsaKeyShare): string { - return teddsaKeyShareToBytes64(share).toHex(); -} - -/** - * Convert 128-char hex string to TeddsaKeyShare. - */ -export function hexToTeddsaKeyShare(hex: string): TeddsaKeyShare { - const bytesResult = Bytes.fromHexString(hex, 64); - if (!bytesResult.success) { - throw new Error( - `Invalid hex string for TeddsaKeyShare: ${bytesResult.err}`, - ); - } - return bytes64ToTeddsaKeyShare(bytesResult.data); -} - -/** - * Convert TeddsaKeyShare to Point256 (same structure, different semantics). - * Use when reusing existing Ed25519 functions. - */ -export function teddsaKeyShareToPoint256(share: TeddsaKeyShare): Point256 { - return { - x: share.identifier, - y: share.signing_share, - }; -} - -/** - * Convert Point256 to TeddsaKeyShare. - */ -export function point256ToTeddsaKeyShare(point: Point256): TeddsaKeyShare { - return { - identifier: point.x, - signing_share: point.y, - }; -} diff --git a/crypto/teddsa/frost_ed25519_keplr/tests/integration_tests.rs b/crypto/teddsa/frost_ed25519_keplr/tests/integration_tests.rs index 8f53095a4..77bb73716 100644 --- a/crypto/teddsa/frost_ed25519_keplr/tests/integration_tests.rs +++ b/crypto/teddsa/frost_ed25519_keplr/tests/integration_tests.rs @@ -379,153 +379,3 @@ fn check_sign_with_incorrect_commitments() { rng, ); } - -/// Test to verify the relationship between identifier and verifying_share. -/// -/// In FROST Ed25519: -/// - identifier: SSS polynomial x-coordinate (scalar, 32 bytes) -/// - signing_share: f(identifier) where f is secret polynomial (scalar, 32 bytes) -/// - verifying_share: signing_share * G (EdwardsPoint, compressed 32 bytes) -/// -/// The compressed EdwardsY format stores: y-coordinate (255 bits) + x sign bit (1 bit) -/// This test extracts the actual x,y coordinates from verifying_share and verifies -/// that identifier is NOT the x-coordinate of the point (it's the polynomial x-value). -#[test] -fn check_identifier_is_not_verifying_share_x_coordinate() { - use curve25519_dalek::edwards::CompressedEdwardsY; - - let mut rng = rand::rngs::OsRng; - - // Generate keys with dealer - let max_signers = 3; - let min_signers = 2; - let (shares, pubkeys) = keys::generate_with_dealer( - max_signers, - min_signers, - keys::IdentifierList::Default, - &mut rng, - ) - .unwrap(); - - // For each participant, check the relationship - for (identifier, secret_share) in &shares { - // Get the key package - let key_package: keys::KeyPackage = secret_share.clone().try_into().unwrap(); - - // Get verifying_share bytes (compressed EdwardsY format) - let verifying_share_bytes = key_package.verifying_share().serialize().unwrap(); - assert_eq!( - verifying_share_bytes.len(), - 32, - "verifying_share should be 32 bytes" - ); - - // Decompress to get actual point coordinates - let compressed = CompressedEdwardsY::from_slice(&verifying_share_bytes).unwrap(); - let point = compressed.decompress().expect("valid point"); - - // Get the actual x and y coordinates (as field elements, in bytes) - // EdwardsPoint internally stores (X, Y, Z, T) in extended coordinates - // To get affine x, y: x = X/Z, y = Y/Z - let point_bytes = point.compress().to_bytes(); - - // Get identifier bytes - let identifier_bytes = identifier.serialize(); - assert_eq!(identifier_bytes.len(), 32, "identifier should be 32 bytes"); - - // The compressed format is y-coordinate with x's sign bit in the MSB - // So the first 255 bits are y, and bit 255 is x's sign - // identifier is a scalar (the x-value in SSS polynomial), NOT the point's x-coordinate - - // Verify that identifier != compressed point bytes (they should be different) - assert_ne!( - identifier_bytes, verifying_share_bytes, - "identifier should NOT equal verifying_share compressed bytes" - ); - - // Also verify that signing_share * G = verifying_share - let signing_share_bytes = key_package.signing_share().serialize(); - assert_eq!( - signing_share_bytes.len(), - 32, - "signing_share should be 32 bytes" - ); - - // The verifying_share from pubkeys should match - let pubkey_verifying_share = pubkeys.verifying_shares().get(identifier).unwrap(); - assert_eq!( - key_package.verifying_share().serialize().unwrap(), - pubkey_verifying_share.serialize().unwrap(), - "verifying_share should match in key_package and public_key_package" - ); - - println!("Participant {:?}:", identifier); - println!( - " identifier bytes: {}", - hex::encode(&identifier_bytes) - ); - println!( - " signing_share bytes: {}", - hex::encode(&signing_share_bytes) - ); - println!( - " verifying_share bytes: {}", - hex::encode(&verifying_share_bytes) - ); - } -} - -/// Test to extract x-coordinate from verifying_share (compressed EdwardsY point). -/// -/// Ed25519 compressed format: y-coordinate (255 bits) + x sign bit (1 bit) = 32 bytes -/// To get x-coordinate, we need to decompress the point. -#[test] -fn check_extract_x_coordinate_from_verifying_share() { - use curve25519_dalek::edwards::CompressedEdwardsY; - - let mut rng = rand::rngs::OsRng; - - let max_signers = 3; - let min_signers = 2; - let (shares, _pubkeys) = keys::generate_with_dealer( - max_signers, - min_signers, - keys::IdentifierList::Default, - &mut rng, - ) - .unwrap(); - - for (identifier, secret_share) in &shares { - let key_package: keys::KeyPackage = secret_share.clone().try_into().unwrap(); - - // Get verifying_share (compressed point) - let verifying_share_bytes = key_package.verifying_share().serialize().unwrap(); - - // Decompress - let compressed = CompressedEdwardsY::from_slice(&verifying_share_bytes).unwrap(); - let point = compressed.decompress().expect("valid point"); - - // Extract y-coordinate from compressed bytes (first 255 bits) - let mut y_bytes = verifying_share_bytes.clone(); - y_bytes[31] &= 0x7F; // Clear the sign bit to get pure y - - // The x sign bit - let x_sign = (verifying_share_bytes[31] >> 7) & 1; - - println!("Participant {:?}:", identifier); - println!( - " compressed bytes: {}", - hex::encode(&verifying_share_bytes) - ); - println!(" y-coordinate: {}", hex::encode(&y_bytes)); - println!(" x sign bit: {}", x_sign); - - // Verify the point is valid by recompressing - let recompressed = point.compress(); - assert_eq!( - recompressed.to_bytes(), - verifying_share_bytes.as_slice(), - "recompressed point should match original" - ); - } -} diff --git a/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/mod.rs b/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/mod.rs index c1d6cbee6..a14896e17 100644 --- a/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/mod.rs +++ b/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/mod.rs @@ -1,9 +1,7 @@ mod identifier; mod key_package; mod public_key_package; -mod scalar_mult; pub use identifier::*; pub use key_package::*; pub use public_key_package::*; -pub use scalar_mult::*; diff --git a/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/scalar_mult.rs b/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/scalar_mult.rs deleted file mode 100644 index d23c78d14..000000000 --- a/crypto/teddsa/frost_ed25519_keplr_wasm/wasm/src/keys/scalar_mult.rs +++ /dev/null @@ -1,78 +0,0 @@ -use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; -use curve25519_dalek::scalar::Scalar; -use gloo_utils::format::JsValueSerdeExt; -use serde::{Deserialize, Serialize}; -use wasm_bindgen::prelude::*; - -#[derive(Serialize, Deserialize)] -pub struct ScalarBaseMultInput { - pub scalar: Vec, -} - -#[derive(Serialize, Deserialize)] -pub struct ScalarBaseMultOutput { - pub point: Vec, -} - -/// Compute verifying_share (point) from signing_share (scalar). -/// verifying_share = signing_share * G (Ed25519 base point) -#[wasm_bindgen] -pub fn scalar_base_mult(input: JsValue) -> Result { - let input: ScalarBaseMultInput = input - .into_serde() - .map_err(|e| JsValue::from_str(&format!("Failed to parse input: {}", e)))?; - - let result = - scalar_base_mult_inner(&input).map_err(|e| JsValue::from_str(&format!("{}", e)))?; - - JsValue::from_serde(&result) - .map_err(|e| JsValue::from_str(&format!("Failed to serialize output: {}", e))) -} - -fn scalar_base_mult_inner(input: &ScalarBaseMultInput) -> Result { - if input.scalar.len() != 32 { - return Err(format!( - "Invalid scalar length: expected 32, got {}", - input.scalar.len() - )); - } - - let scalar_bytes: [u8; 32] = input - .scalar - .clone() - .try_into() - .map_err(|_| "Failed to convert scalar bytes")?; - - let scalar = Scalar::from_bytes_mod_order(scalar_bytes); - let point = &scalar * ED25519_BASEPOINT_TABLE; - let point_bytes = point.compress().to_bytes(); - - Ok(ScalarBaseMultOutput { - point: point_bytes.to_vec(), - }) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_scalar_base_mult_valid() { - let mut scalar = vec![0u8; 32]; - scalar[0] = 1; - - let input = ScalarBaseMultInput { scalar }; - let result = scalar_base_mult_inner(&input).unwrap(); - - assert_eq!(result.point.len(), 32); - } - - #[test] - fn test_scalar_base_mult_invalid_length() { - let input = ScalarBaseMultInput { - scalar: vec![1u8; 16], - }; - let result = scalar_base_mult_inner(&input); - assert!(result.is_err()); - } -} diff --git a/embed/oko_attached/src/crypto/scalar.ts b/embed/oko_attached/src/crypto/scalar.ts deleted file mode 100644 index 752a1d85b..000000000 --- a/embed/oko_attached/src/crypto/scalar.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { Bytes32 } from "@oko-wallet/bytes"; -import { Bytes } from "@oko-wallet/bytes"; -import { wasmModule } from "@oko-wallet/frost-ed25519-keplr-wasm"; - -interface TeddsaScalarBaseMultInput { - scalar: number[]; -} - -interface TeddsaScalarBaseMultOutput { - point: number[]; -} - -/** - * Compute verifying_share from signing_share. - * Ed25519: verifying_share = signing_share * G (base point) - * - * Used to reconstruct KeyPackage from SSS-recovered signing_share. - * - * @param signingShare - 32-byte signing_share - * @returns 32-byte verifying_share (compressed Ed25519 point) - */ -export function computeVerifyingShare(signingShare: Bytes32): Bytes32 { - const input: TeddsaScalarBaseMultInput = { - scalar: Array.from(signingShare.toUint8Array()), - }; - - const output: TeddsaScalarBaseMultOutput = wasmModule.scalar_base_mult(input); - - const result = Bytes.fromUint8Array(new Uint8Array(output.point), 32); - if (!result.success) { - throw new Error(`Invalid verifying_share output: ${result.err}`); - } - - return result.data; -} diff --git a/embed/oko_attached/src/crypto/sss_ed25519.ts b/embed/oko_attached/src/crypto/sss_ed25519.ts index 50d375fad..d1c0b9476 100644 --- a/embed/oko_attached/src/crypto/sss_ed25519.ts +++ b/embed/oko_attached/src/crypto/sss_ed25519.ts @@ -1,187 +1,241 @@ -import type { KeyShareNodeMetaWithNodeStatusInfo } from "@oko-wallet/oko-types/tss"; -import { wasmModule } from "@oko-wallet/frost-ed25519-keplr-wasm"; -import { Bytes, type Bytes32 } from "@oko-wallet/bytes"; -import type { TeddsaKeyShareByNode } from "@oko-wallet/oko-types/user_key_share"; -import type { Result } from "@oko-wallet/stdlib-js"; -import type { - KeyPackage, - KeyPackageRaw, - PublicKeyPackageRaw, -} from "@oko-wallet/teddsa-interface"; - -import { hashKeyshareNodeNamesEd25519 } from "./hash"; -import { computeVerifyingShare } from "./scalar"; - -interface SplitOutputRaw { - key_packages: KeyPackageRaw[]; - public_key_package: PublicKeyPackageRaw; -} - -/** - * Split client signing_share using SSS for KS node distribution. - * - * Uses FROST's sss_split to split the signing_share. - * Extracts identifier and signing_share from each KeyPackage. - * - * @param signingShare - FROST KeyPackage's signing_share (32 bytes) - * @param keyshareNodeMeta - KS Node metadata (nodes, threshold) - * @returns TeddsaKeyShareByNode[] - (identifier, signing_share) pairs per node - */ -export async function splitTeddsaSigningShare( - signingShare: Bytes32, - keyshareNodeMeta: KeyShareNodeMetaWithNodeStatusInfo, -): Promise> { - try { - const signingShareArr = [...signingShare.toUint8Array()]; - - const identifiersRes = await hashKeyshareNodeNamesEd25519( - keyshareNodeMeta.nodes.map((n) => n.name), - ); - if (!identifiersRes.success) { - return { success: false, err: identifiersRes.err }; - } - - const identifiers = identifiersRes.data.map((b) => [...b.toUint8Array()]); - - const splitOutput: SplitOutputRaw = wasmModule.sss_split( - signingShareArr, - identifiers, - keyshareNodeMeta.threshold, - ); - - const shares: TeddsaKeyShareByNode[] = splitOutput.key_packages.map( - (kp, i) => { - const idBytes = Bytes.fromUint8Array( - new Uint8Array(kp.identifier), - 32, - ); - const shareBytes = Bytes.fromUint8Array( - new Uint8Array(kp.signing_share), - 32, - ); - - if (!idBytes.success) throw new Error(idBytes.err); - if (!shareBytes.success) throw new Error(shareBytes.err); - - return { - node: { - name: keyshareNodeMeta.nodes[i].name, - endpoint: keyshareNodeMeta.nodes[i].endpoint, - }, - share: { - identifier: idBytes.data, - signing_share: shareBytes.data, - }, - }; - }, - ); - - return { success: true, data: shares }; - } catch (e) { - return { - success: false, - err: `splitTeddsaSigningShare failed: ${String(e)}`, - }; - } -} - -/** - * Combine shares from KS nodes to recover signing_share. - * - * Converts TeddsaKeyShares to KeyPackageRaw format for sss_combine. - * - * @param shares - TeddsaKeyShare array from KS nodes - * @param threshold - SSS threshold (minimum shares required) - * @param verifyingKey - PublicKeyPackage's verifying_key (needed for KeyPackageRaw) - * @returns signing_share (32 bytes) - */ -export async function combineTeddsaShares( - shares: TeddsaKeyShareByNode[], - threshold: number, - verifyingKey: Bytes32, -): Promise> { - try { - if (shares.length < threshold) { - return { - success: false, - err: `Not enough shares: got ${shares.length}, need ${threshold}`, - }; - } - - const keyPackages: KeyPackageRaw[] = shares.map((s) => { - const verifyingShare = computeVerifyingShare(s.share.signing_share); - - return { - identifier: [...s.share.identifier.toUint8Array()], - signing_share: [...s.share.signing_share.toUint8Array()], - verifying_share: [...verifyingShare.toUint8Array()], - verifying_key: [...verifyingKey.toUint8Array()], - min_signers: threshold, - }; - }); - - const combined: number[] = wasmModule.sss_combine(keyPackages); - - const result = Bytes.fromUint8Array(Uint8Array.from(combined), 32); - if (!result.success) { - return { success: false, err: result.err }; - } - - return { success: true, data: result.data }; - } catch (e) { - return { success: false, err: `combineTeddsaShares failed: ${String(e)}` }; - } -} - -/** - * Reconstruct KeyPackage from recovered signing_share. - * - * Computes verifying_share from signing_share to create complete KeyPackage. - * - * @param signingShare - SSS-recovered client signing_share - * @param frostIdentifier - FROST P0 identifier (client is always 1) - * @param verifyingKey - PublicKeyPackage's verifying_key - * @param minSigners - threshold (2 for 2-of-2) - * @returns Complete FROST KeyPackage - */ -export function reconstructKeyPackage( - signingShare: Bytes32, - frostIdentifier: Bytes32, - verifyingKey: Bytes32, - minSigners: number, -): KeyPackage { - const verifyingShare = computeVerifyingShare(signingShare); - - return { - identifier: frostIdentifier, - signing_share: signingShare, - verifying_share: verifyingShare, - verifying_key: verifyingKey, - min_signers: minSigners, - }; -} - -/** - * Extract signing_share from KeyPackageRaw. - */ -export function extractSigningShare( - keyPackage: KeyPackageRaw, -): Result { - const signingShareRes = Bytes.fromUint8Array( - new Uint8Array(keyPackage.signing_share), - 32, - ); - if (!signingShareRes.success) { - return { success: false, err: signingShareRes.err }; - } - return { success: true, data: signingShareRes.data }; -} - -/** - * Extract signing_share from KeyPackage (Bytes type). - */ -export function extractSigningShareFromKeyPackage( - keyPackage: KeyPackage, -): Bytes32 { - return keyPackage.signing_share; -} +// refactor this file @chemonoworld + +// import type { KeyShareNodeMetaWithNodeStatusInfo } from "@oko-wallet/oko-types/tss"; +// import { wasmModule } from "@oko-wallet/frost-ed25519-keplr-wasm"; +// import { Bytes, type Bytes32 } from "@oko-wallet/bytes"; +// import type { +// PointNumArr, +// UserKeySharePointByNode, +// } from "@oko-wallet/oko-types/user_key_share"; +// import type { TeddsaKeygenOutputBytes } from "@oko-wallet/teddsa-hooks"; +// import type { Result } from "@oko-wallet/stdlib-js"; + +// import { hashKeyshareNodeNamesEd25519 } from "./hash"; + +// /** +// * Data structure for Ed25519 key share backup on KS nodes. +// * Contains the SSS split of signing_share along with public info needed for reconstruction. +// */ +// export interface Ed25519KeyShareBackup { +// /** SSS split point (x: identifier, y: share) */ +// share: { +// x: Bytes32; +// y: Bytes32; +// }; +// /** Serialized PublicKeyPackage (needed for reconstruction) */ +// publicKeyPackage: string; // hex string +// /** Participant identifier (needed for reconstruction) */ +// identifier: string; // hex string +// /** Ed25519 public key (for verification) */ +// publicKey: string; // hex string +// } + +// /** +// * Split Ed25519 key package for backup on Key Share Nodes. +// * +// * Extracts the signing_share from the key_package and splits it using SSS. +// * Also includes the public information needed to reconstruct the key_package. +// */ +// export async function splitUserKeySharesEd25519( +// keygen_1: TeddsaKeygenOutputBytes, +// keyshareNodeMeta: KeyShareNodeMetaWithNodeStatusInfo, +// ): Promise> { +// try { +// const keyPackageBytes = [...keygen_1.key_package]; + +// // Extract signing_share from key_package (32-byte scalar) +// const signingShareArr: number[] = +// wasmModule.extract_signing_share(keyPackageBytes); + +// // Hash KS node names to get identifiers for SSS (Ed25519-compatible) +// const keyshareNodeHashesRes = await hashKeyshareNodeNamesEd25519( +// keyshareNodeMeta.nodes.map((meta) => meta.name), +// ); +// if (keyshareNodeHashesRes.success === false) { +// return { +// success: false, +// err: keyshareNodeHashesRes.err, +// }; +// } +// const keyshareNodeHashes = keyshareNodeHashesRes.data.map((bytes) => { +// return [...bytes.toUint8Array()]; +// }); + +// // Split signing_share using SSS +// const splitPoints: PointNumArr[] = wasmModule.sss_split( +// signingShareArr, +// keyshareNodeHashes, +// keyshareNodeMeta.threshold, +// ); + +// // Convert to UserKeySharePointByNode format +// const shares: UserKeySharePointByNode[] = splitPoints.map( +// (point: PointNumArr, index: number) => { +// const xBytesRes = Bytes.fromUint8Array( +// Uint8Array.from([...point.x]), +// 32, +// ); +// if (xBytesRes.success === false) { +// throw new Error(xBytesRes.err); +// } +// const yBytesRes = Bytes.fromUint8Array( +// Uint8Array.from([...point.y]), +// 32, +// ); +// if (yBytesRes.success === false) { +// throw new Error(yBytesRes.err); +// } +// return { +// node: { +// name: keyshareNodeMeta.nodes[index].name, +// endpoint: keyshareNodeMeta.nodes[index].endpoint, +// }, +// share: { +// x: xBytesRes.data, +// y: yBytesRes.data, +// }, +// }; +// }, +// ); + +// return { +// success: true, +// data: shares, +// }; +// } catch (error: any) { +// return { +// success: false, +// err: `splitUserKeySharesEd25519 failed: ${String(error)}`, +// }; +// } +// } + +// /** +// * Combine Ed25519 key shares to recover the signing_share. +// */ +// export async function combineUserSharesEd25519( +// userKeySharePoints: UserKeySharePointByNode[], +// threshold: number, +// ): Promise> { +// try { +// if (threshold < 2) { +// return { +// success: false, +// err: "Threshold must be at least 2", +// }; +// } + +// if (userKeySharePoints.length < threshold) { +// return { +// success: false, +// err: "Number of user key shares is less than threshold", +// }; +// } + +// const points: PointNumArr[] = userKeySharePoints.map( +// (userKeySharePoint) => ({ +// x: [...userKeySharePoint.share.x.toUint8Array()], +// y: [...userKeySharePoint.share.y.toUint8Array()], +// }), +// ); + +// // Combine shares to recover signing_share +// const combinedSigningShare: number[] = wasmModule.sss_combine( +// points, +// threshold, +// ); + +// return { +// success: true, +// data: Uint8Array.from(combinedSigningShare), +// }; +// } catch (e) { +// return { +// success: false, +// err: `combineUserSharesEd25519 failed: ${String(e)}`, +// }; +// } +// } + +// /** +// * Reconstruct a full KeyPackage from a recovered signing_share and public info. +// */ +// export async function reconstructKeyPackageEd25519( +// signingShare: Uint8Array, +// publicKeyPackage: Uint8Array, +// identifier: Uint8Array, +// ): Promise> { +// try { +// const keyPackageArr: number[] = wasmModule.reconstruct_key_package( +// [...signingShare], +// [...publicKeyPackage], +// [...identifier], +// ); + +// return { +// success: true, +// data: Uint8Array.from(keyPackageArr), +// }; +// } catch (e) { +// return { +// success: false, +// err: `reconstructKeyPackageEd25519 failed: ${String(e)}`, +// }; +// } +// } + +// /** +// * Full recovery of Ed25519 keygen output from KS node shares. +// * +// * Given the SSS shares from KS nodes plus the stored public info, +// * reconstructs the complete TeddsaKeygenOutputBytes. +// */ +// export async function recoverEd25519Keygen( +// userKeySharePoints: UserKeySharePointByNode[], +// threshold: number, +// publicKeyPackage: Uint8Array, +// identifier: Uint8Array, +// publicKey: Bytes32, +// ): Promise> { +// try { +// // Combine shares to recover signing_share +// const combineRes = await combineUserSharesEd25519( +// userKeySharePoints, +// threshold, +// ); +// if (!combineRes.success) { +// return { +// success: false, +// err: combineRes.err, +// }; +// } + +// // Reconstruct key_package from signing_share + public info +// const reconstructRes = await reconstructKeyPackageEd25519( +// combineRes.data, +// publicKeyPackage, +// identifier, +// ); +// if (!reconstructRes.success) { +// return { +// success: false, +// err: reconstructRes.err, +// }; +// } + +// return { +// success: true, +// data: { +// key_package: reconstructRes.data, +// public_key_package: publicKeyPackage, +// identifier: identifier, +// public_key: publicKey, +// }, +// }; +// } catch (e) { +// return { +// success: false, +// err: `recoverEd25519Keygen failed: ${String(e)}`, +// }; +// } +// } diff --git a/internals/ci/src/cmds/build_frost.ts b/internals/ci/src/cmds/build_frost.ts index d8ea8c02d..9aea276b8 100644 --- a/internals/ci/src/cmds/build_frost.ts +++ b/internals/ci/src/cmds/build_frost.ts @@ -14,10 +14,11 @@ export async function buildFrost(..._args: any[]) { expectSuccess(wasmRet, "wasm build failed"); console.log("%s %s", chalk.bold.green("Done"), "build wasm frost keplr"); - const copyRet = spawnSync("yarn", ["run", "copy_wasm"], { - cwd: paths.oko_attached, - stdio: "inherit", - }); - expectSuccess(copyRet, "copy failed"); - console.log("%s %s", chalk.bold.green("Done"), "copy wasm"); + // TODO: copy wasm to oko_attached or other target locations @chemonoworld + // const copyRet = spawnSync("yarn", ["run", "copy_wasm"], { + // cwd: paths.oko_attached, + // stdio: "inherit", + // }); + // expectSuccess(copyRet, "copy failed"); + // console.log("%s %s", chalk.bold.green("Done"), "copy wasm"); } diff --git a/key_share_node/ksn_interface/src/key_share.ts b/key_share_node/ksn_interface/src/key_share.ts index e827295ed..88b3e2d1a 100644 --- a/key_share_node/ksn_interface/src/key_share.ts +++ b/key_share_node/ksn_interface/src/key_share.ts @@ -27,21 +27,6 @@ export type UpdateKeyShareRequest = { status: KeyShareStatus; }; -/** - * Key share registration request for KS node. - * - * Share format by curve_type (both are 64 bytes): - * - * secp256k1: - * Point256 { x: 32 bytes, y: 32 bytes } - * - Elliptic curve point coordinates - * - * ed25519 (TEDDSA): - * TeddsaKeyShare { identifier: 32 bytes, signing_share: 32 bytes } - * - identifier: SSS x-coordinate (node_name SHA256 hash, byte[31] &= 0x0F) - * - signing_share: SSS y-coordinate (split signing share) - * - Note: verifying_share is recovered from signing_share via scalar_base_mult - */ export interface RegisterKeyShareRequest { user_auth_id: string; auth_type: AuthType; @@ -91,12 +76,6 @@ export interface CheckKeyShareRequestBody { public_key: string; // hex string } -/** - * Key share reshare request for KS node. - * - * Share format is same as RegisterKeyShareRequest (64 bytes). - * See RegisterKeyShareRequest for detailed format by curve_type. - */ export interface ReshareKeyShareRequest { user_auth_id: string; auth_type: AuthType;