From 7467e2bd709c2f8fb9db3dc747916c8317375395 Mon Sep 17 00:00:00 2001 From: Sasha Mitchell Date: Fri, 25 Sep 2026 15:58:53 +0700 Subject: [PATCH] fix: reject underscores in derivation indexes der_to_bytes used int() on each path component. int("1_0") is 10, so m/1_0 encoded index 10. Indexes now have to be digits. --- src/cryptoadvance/specter/helpers.py | 2 ++ tests/test_der_to_bytes.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/test_der_to_bytes.py diff --git a/src/cryptoadvance/specter/helpers.py b/src/cryptoadvance/specter/helpers.py index 0dc9037c7..9d9d60e25 100644 --- a/src/cryptoadvance/specter/helpers.py +++ b/src/cryptoadvance/specter/helpers.py @@ -232,6 +232,8 @@ def der_to_bytes(derivation): if item[-1] == "h" or item[-1] == "'": index += 0x80000000 item = item[:-1] + if not item.isdigit(): + raise ValueError(f"Invalid derivation index: {item}") index += int(item) res += index.to_bytes(4, "little") return res diff --git a/tests/test_der_to_bytes.py b/tests/test_der_to_bytes.py new file mode 100644 index 000000000..b80157ea2 --- /dev/null +++ b/tests/test_der_to_bytes.py @@ -0,0 +1,21 @@ +import unittest + +from cryptoadvance.specter.helpers import der_to_bytes + + +class TestDerToBytes(unittest.TestCase): + def test_underscore_is_rejected(self): + with self.assertRaises(ValueError): + der_to_bytes("m/1_0") + + def test_plain_index(self): + self.assertEqual(der_to_bytes("m/10"), (10).to_bytes(4, "little")) + + def test_hardened_index(self): + self.assertEqual( + der_to_bytes("m/1h"), (0x80000001).to_bytes(4, "little") + ) + + +if __name__ == "__main__": + unittest.main()