summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Zelawski <pawel.zelawski@outlook.com>2026-01-23 11:37:56 +0100
committerPawel Zelawski <pawel.zelawski@outlook.com>2026-01-23 11:37:56 +0100
commitfbc80fe79ce823534a58197dd3173f29f81d6bcb (patch)
tree3cbb05850a7ee33ff951b55b469704cbbcfb99ec
parent491058ae03ba1f0ae70fe3c684002c9e8e864a53 (diff)
fix: correct public key recovery to use toBytes() and addRecoveryBit()
- Changed point.toRawBytes() to point.toBytes() to match @noble/curves v2 API - Added .addRecoveryBit(actualRecoveryId) to signature for proper recovery - Returns both compressed/uncompressed public keys for verification - Fixes signature verification regression in v2.0.0
-rw-r--r--package.json4
-rw-r--r--src/digiid.ts27
2 files changed, 17 insertions, 14 deletions
diff --git a/package.json b/package.json
index e326047..1edba61 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "digiid-ts",
- "version": "2.0.0",
+ "version": "2.0.1-beta.0",
"description": "A modern TypeScript implementation of the DigiID authentication protocol.",
"main": "dist/digiid-ts.umd.js",
"module": "dist/digiid-ts.es.js",
@@ -78,4 +78,4 @@
"glob": "^10.5.0",
"brace-expansion": "^2.0.2"
}
-}
+} \ No newline at end of file
diff --git a/src/digiid.ts b/src/digiid.ts
index 11bc309..168e097 100644
--- a/src/digiid.ts
+++ b/src/digiid.ts
@@ -178,7 +178,7 @@ function recoverPublicKey(messageHash: Uint8Array, signature: Uint8Array): Uint8
const compressed = recoveryId >= 4;
const actualRecoveryId = recoveryId % 4;
- if (actualRecoveryId > 3) {
+ if (actualRecoveryId < 0 || actualRecoveryId > 3) {
throw new Error('Invalid recovery ID');
}
@@ -189,20 +189,23 @@ function recoverPublicKey(messageHash: Uint8Array, signature: Uint8Array): Uint8
const sig = new secp256k1.Signature(
BigInt('0x' + Array.from(r).map(b => b.toString(16).padStart(2, '0')).join('')),
BigInt('0x' + Array.from(s).map(b => b.toString(16).padStart(2, '0')).join(''))
- );
+ ).addRecoveryBit(actualRecoveryId);
try {
const point = sig.recoverPublicKey(messageHash);
- return [point.toHex(compressed)].map(hex => {
- // Convert hex string to Uint8Array
- const bytes = new Uint8Array(hex.length / 2);
- for (let i = 0; i < hex.length; i += 2) {
- bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
- }
- return bytes;
- });
- } catch {
- throw new Error('Failed to recover public key');
+ // Return both compressed and uncompressed versions to try both
+ const compressedBytes = point.toBytes(true);
+ const uncompressedBytes = point.toBytes(false);
+
+ // Based on the recoveryId flag, return the appropriate format(s)
+ if (compressed) {
+ return [compressedBytes];
+ } else {
+ // For uncompressed signatures, try both formats as different wallets may encode differently
+ return [uncompressedBytes, compressedBytes];
+ }
+ } catch (e) {
+ throw new Error('Failed to recover public key: ' + (e instanceof Error ? e.message : String(e)));
}
}