Files
seedpgp-web/src/lib/seedqr.test.ts
LC mac 75da988968 test(crypto): Fix Base43 leading zeros and Krux KEF compatibility
**🔧 Critical Fixes for Krux Hardware Wallet Compatibility**

### Base43 Encoding (Leading Zero Preservation)
- Fix base43Decode to preserve leading zero bytes
- Add proper boundary handling for empty strings and all-zero inputs
- Match Krux Python implementation exactly
- Prevents decryption failures with Krux encrypted data

### Krux KEF (Krux Encryption Format)
- Fix iterations scaling: store value/10000 when divisible by 10000
- Add label length validation (max 252 chars)
- Correct error validation order in decryptFromKrux
- Fix boundary case: iterations = 10000 exactly

### SeedBlend Crypto Compatibility
- Update getCrypto() to work in test environment
- Remove import.meta.env.SSR check for better Node.js/Bun compatibility

**Test Results:**
-  All 60 tests passing
-  100% Krux compatibility verified
-  Real-world test vectors validated

**Breaking Changes:** None - pure bug fixes for edge cases
2026-02-09 00:09:11 +08:00

36 lines
1.6 KiB
TypeScript

// seedqr.test.ts
import { describe, it, expect } from "bun:test";
import { encodeStandardSeedQR, encodeCompactSeedQREntropy } from './seedqr';
describe('SeedQR encoding (SeedSigner test vectors)', () => {
it('encodes 24-word seed to correct Standard SeedQR digit stream (Test Vector 3)', async () => {
const mnemonic =
'sound federal bonus bleak light raise false engage round stock update render quote truck quality fringe palace foot recipe labor glow tortoise potato still';
const expectedDigitStream =
'166206750203018810361417065805941507171219081456140818651401074412730727143709940798183613501710';
const result = await encodeStandardSeedQR(mnemonic);
expect(result).toBe(expectedDigitStream);
});
it('encodes 12-word seed to correct Standard and Compact SeedQR (Test Vector 4)', async () => {
const mnemonic =
'forum undo fragile fade shy sign arrest garment culture tube off merit';
const expectedStandardDigitStream =
'073318950739065415961602009907670428187212261116';
const expectedCompactBitStream = '01011011101111011001110101110001101010001110110001111001100100001000001100011010111111110011010110011101010000100110010101000101';
const standard = await encodeStandardSeedQR(mnemonic);
expect(standard).toBe(expectedStandardDigitStream);
const compactEntropy = await encodeCompactSeedQREntropy(mnemonic);
const bitString = Array.from(compactEntropy)
.map((byte) => byte.toString(2).padStart(8, '0'))
.join('');
expect(bitString).toBe(expectedCompactBitStream);
});
});