feat: Implement Krux KEF encryption compatibility

This commit is contained in:
LC mac
2026-02-08 01:36:17 +08:00
parent 008406ef59
commit 54195ead8d
10 changed files with 203 additions and 99 deletions

View File

@@ -1,9 +1,8 @@
// src/lib/krux.ts
// Krux KEF (Krux Encryption Format) implementation
import * as pako from 'pako';
import { base43Decode } from './base43';
// KEF version definitions, ported from kef.py
import { base43Decode, base43Encode } from './base43';
import { getWalletFingerprint } from './bip32';
export const VERSIONS: Record<number, {
name: string;
compress: boolean;
@@ -168,16 +167,27 @@ export function bytesToHex(bytes: Uint8Array): string {
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase();
}
export async function encryptToKrux(params: { mnemonic: string; passphrase: string; label?: string; iterations?: number; version?: number; }): Promise<{ kefHex: string; label: string; version: number; iterations: number }> {
const { mnemonic, passphrase, label = "Seed Backup", iterations = 200000, version = 21 } = params;
if (!passphrase) throw new Error("Passphrase is required for Krux encryption");
export async function encryptToKrux(params: {
mnemonic: string;
passphrase: string;
}): Promise<{ kefBase43: string; label: string; version: number; iterations: number }> {
const { mnemonic, passphrase } = params;
if (!passphrase) throw new Error("Passphrase is required");
const label = getWalletFingerprint(mnemonic);
const iterations = 100000;
const version = 20;
const mnemonicBytes = await mnemonicToEntropy(mnemonic);
// For encryption, we encode the string label to get the salt bytes
const cipher = new KruxCipher(passphrase, new TextEncoder().encode(label), iterations);
const payload = await cipher.encrypt(mnemonicBytes, version);
const kef = wrap(label, version, iterations, payload);
return { kefHex: bytesToHex(kef), label, version, iterations };
const kefBase43 = base43Encode(kef);
console.log('🔐 KEF Debug:', { label, iterations, version, length: kef.length, base43: kefBase43.slice(0, 50) });
return { kefBase43, label, version, iterations };
}
export function wrap(label: string, version: number, iterations: number, payload: Uint8Array): Uint8Array {