test(crypto): cover Slip132 rejection of malformed and corrupted keys

TryDecodePublic/TryDecodePrivate return false on several inputs that
weren't exercised: well-formed Base58Check with a payload that isn't
78 bytes, and a correct SLIP-132 header with a corrupted key body
(bad pubkey point prefix / bad private-key padding byte) — both must
fail cleanly inside the try/catch, not throw.
This commit is contained in:
2026-07-07 16:24:52 +02:00
parent 56135c29f8
commit 2ed8c04064
@@ -1,4 +1,5 @@
using NBitcoin;
using NBitcoin.DataEncoders;
using PalladiumWallet.Core.Chain;
using PalladiumWallet.Core.Crypto;
@@ -74,6 +75,39 @@ public class Bip84Slip132Tests
Assert.False(Slip132.TryDecodePrivate(asXpub, ChainProfiles.Mainnet, out _, out _)); // pub ≠ priv
}
[Fact]
public void Una_xkey_base58_valida_ma_di_lunghezza_sbagliata_viene_rifiutata()
{
// Well-formed Base58Check, but the decoded payload is not 78 bytes.
var tooShort = Encoders.Base58Check.EncodeData([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Assert.False(Slip132.TryDecodePublic(tooShort, ChainProfiles.Mainnet, out _, out _));
Assert.False(Slip132.TryDecodePrivate(tooShort, ChainProfiles.Mainnet, out _, out _));
}
[Fact]
public void Una_zpub_con_payload_corrotto_viene_rifiutata_senza_eccezioni()
{
// Correct zpub header, but the 33-byte pubkey has an invalid point prefix:
// the ExtPubKey constructor must fail and TryDecodePublic must return false.
var data = Encoders.Base58Check.DecodeData(Account().ToSlip132());
data[45] = 0xFF; // pubkey prefix (offset 4 header + 41) — not 0x02/0x03
var corrupted = Encoders.Base58Check.EncodeData(data);
Assert.False(Slip132.TryDecodePublic(corrupted, ChainProfiles.Mainnet, out _, out _));
}
[Fact]
public void Una_zprv_con_payload_corrotto_viene_rifiutata_senza_eccezioni()
{
// Correct zprv header, but the byte before the 32-byte key must be 0x00:
// ExtKey.CreateFromBytes must fail and TryDecodePrivate must return false.
var data = Encoders.Base58Check.DecodeData(Account().ToSlip132Private());
data[45] = 0xFF;
var corrupted = Encoders.Base58Check.EncodeData(data);
Assert.False(Slip132.TryDecodePrivate(corrupted, ChainProfiles.Mainnet, out _, out _));
}
[Theory]
[InlineData(false, 0, "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c",
"bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu")]