mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-07 09:57:50 +08:00
feat: fix CompactSeedQR binary QR code scanning with jsQR library
- Replace BarcodeDetector with jsQR for raw binary byte access - BarcodeDetector forced UTF-8 decoding which corrupted binary data - jsQR's binaryData property preserves raw bytes without text conversion - Fix regex bug: use single backslash \x00 instead of \x00 for binary detection - Add debug logging for scan data inspection - QR generation already worked (Krux-compatible), only scanning was broken Resolves binary QR code scanning for 12/24-word CompactSeedQR format. Tested with Krux device - full bidirectional compatibility confirmed.
This commit is contained in:
@@ -39,13 +39,22 @@ function getCrypto(): Promise<SubtleCrypto> {
|
||||
if (typeof window !== 'undefined' && window.crypto?.subtle) {
|
||||
return window.crypto.subtle;
|
||||
}
|
||||
const { webcrypto } = await import('crypto');
|
||||
return webcrypto.subtle;
|
||||
if (import.meta.env.SSR) {
|
||||
const { webcrypto } = await import('crypto');
|
||||
return webcrypto.subtle as SubtleCrypto;
|
||||
}
|
||||
throw new Error("SubtleCrypto not found in this environment");
|
||||
})();
|
||||
}
|
||||
return cryptoPromise;
|
||||
}
|
||||
|
||||
function toArrayBuffer(data: Uint8Array): ArrayBuffer {
|
||||
const buffer = new ArrayBuffer(data.byteLength);
|
||||
new Uint8Array(buffer).set(data);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// --- BIP39 Wordlist Loading ---
|
||||
|
||||
/**
|
||||
@@ -74,7 +83,7 @@ if (BIP39_WORDLIST.length !== 2048) {
|
||||
*/
|
||||
async function sha256(data: Uint8Array): Promise<Uint8Array> {
|
||||
const subtle = await getCrypto();
|
||||
const hashBuffer = await subtle.digest('SHA-256', data);
|
||||
const hashBuffer = await subtle.digest('SHA-256', toArrayBuffer(data));
|
||||
return new Uint8Array(hashBuffer);
|
||||
}
|
||||
|
||||
@@ -88,12 +97,12 @@ async function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Uint8Array
|
||||
const subtle = await getCrypto();
|
||||
const cryptoKey = await subtle.importKey(
|
||||
'raw',
|
||||
key,
|
||||
toArrayBuffer(key),
|
||||
{ name: 'HMAC', hash: 'SHA-256' },
|
||||
false, // not exportable
|
||||
['sign']
|
||||
);
|
||||
const signature = await subtle.sign('HMAC', cryptoKey, data);
|
||||
const signature = await subtle.sign('HMAC', cryptoKey, toArrayBuffer(data));
|
||||
return new Uint8Array(signature);
|
||||
}
|
||||
|
||||
@@ -143,7 +152,7 @@ export async function hkdfExtractExpand(
|
||||
dataToHmac.set(info, t.length);
|
||||
dataToHmac.set([counter], t.length + info.length);
|
||||
|
||||
t = await hmacSha256(prk, dataToHmac);
|
||||
t = new Uint8Array(await hmacSha256(prk, dataToHmac));
|
||||
|
||||
const toWrite = Math.min(t.length, length - written);
|
||||
okm.set(t.slice(0, toWrite), written);
|
||||
@@ -322,7 +331,7 @@ export function calculateDiceStats(diceRolls: string): DiceStats {
|
||||
const sum = rolls.reduce((a, b) => a + b, 0);
|
||||
const mean = sum / n;
|
||||
|
||||
const variance = rolls.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / n;
|
||||
|
||||
const stdDev = n > 1 ? Math.sqrt(rolls.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / (n - 1)) : 0;
|
||||
|
||||
const estimatedEntropyBits = n * Math.log2(6);
|
||||
|
||||
Reference in New Issue
Block a user