From f53b1fed3656df2de3a40f242058697f1884f5f7 Mon Sep 17 00:00:00 2001 From: Dagur Valberg Johannsson Date: Wed, 16 Sep 2026 14:31:01 +0200 Subject: [PATCH 1/2] fix(vm): accept DER signature length boundaries BCHN's IsValidDERSignatureEncoding accepts raw DER signatures from 8 through 72 bytes, inclusive. References: - https://github.com/bitcoin-cash-node/bitcoin-cash-node/blob/b31ed10b4aa4ea54c0a20ed3e536cca05759887c/src/script/sigencoding.cpp - https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki --- .../instruction-sets/common/encoding.spec.ts | 36 +++++++++++++++++++ .../vm/instruction-sets/common/encoding.ts | 4 +-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/lib/vm/instruction-sets/common/encoding.spec.ts diff --git a/src/lib/vm/instruction-sets/common/encoding.spec.ts b/src/lib/vm/instruction-sets/common/encoding.spec.ts new file mode 100644 index 00000000..d33f8b4f --- /dev/null +++ b/src/lib/vm/instruction-sets/common/encoding.spec.ts @@ -0,0 +1,36 @@ +import test from 'ava'; + +import { isValidSignatureEncodingDER, range } from '../../../lib.js'; + +const minimumLengthSignature = Uint8Array.from([ + 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, +]); +const maximumLengthInteger = [0, ...range(32).map(() => 0x80)]; +const maximumLengthSignature = Uint8Array.from([ + 0x30, + 0x46, + 0x02, + 0x21, + ...maximumLengthInteger, + 0x02, + 0x21, + ...maximumLengthInteger, +]); +const oversizedInteger = [0, ...range(33).map(() => 0x80)]; +const oversizedSignature = Uint8Array.from([ + 0x30, + 0x47, + 0x02, + 0x22, + ...oversizedInteger, + 0x02, + 0x21, + ...maximumLengthInteger, +]); + +test('isValidSignatureEncodingDER: length boundaries', (t) => { + t.false(isValidSignatureEncodingDER(minimumLengthSignature.slice(0, -1))); + t.true(isValidSignatureEncodingDER(minimumLengthSignature)); + t.true(isValidSignatureEncodingDER(maximumLengthSignature)); + t.false(isValidSignatureEncodingDER(oversizedSignature)); +}); diff --git a/src/lib/vm/instruction-sets/common/encoding.ts b/src/lib/vm/instruction-sets/common/encoding.ts index cac63230..2c0d344d 100644 --- a/src/lib/vm/instruction-sets/common/encoding.ts +++ b/src/lib/vm/instruction-sets/common/encoding.ts @@ -86,8 +86,8 @@ const isValidInteger = ( // eslint-disable-next-line complexity export const isValidSignatureEncodingDER = (signature: Uint8Array) => { const correctLengthRange = - signature.length > DER.minimumLength && - signature.length < DER.maximumLength; + signature.length >= DER.minimumLength && + signature.length <= DER.maximumLength; const correctSequenceTagType = signature[DER.sequenceTagIndex] === ASN1.sequenceTagType; const correctSequenceLength = From dbd73babb2864833f759a49a2fe8f92881e594db Mon Sep 17 00:00:00 2001 From: Dagur Valberg Johannsson Date: Wed, 16 Sep 2026 15:23:57 +0200 Subject: [PATCH 2/2] chore: add DER encoding fix changeset --- .changeset/warm-signatures-smile.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/warm-signatures-smile.md diff --git a/.changeset/warm-signatures-smile.md b/.changeset/warm-signatures-smile.md new file mode 100644 index 00000000..b30bcd60 --- /dev/null +++ b/.changeset/warm-signatures-smile.md @@ -0,0 +1,5 @@ +--- +'@bitauth/libauth': patch +--- + +Fix `isValidSignatureEncodingDER` to accept valid 8- and 72-byte DER signatures