Skip to content

Commit 62f222f

Browse files
committed
Reject splitting negative amounts
1 parent e4ff0ed commit 62f222f

5 files changed

Lines changed: 12 additions & 30 deletions

File tree

‎NBitcoin.Tests/Secp256k1Tests.cs‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4557,18 +4557,6 @@ public void schnorr_adaptor_tests()
45574557
}
45584558
}
45594559

4560-
[Fact]
4561-
[Trait("UnitTest", "UnitTest")]
4562-
public void bip340_rejects_non_32_byte_messages()
4563-
{
4564-
var key = ECPrivKey.Create(new byte[32] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
4565-
var message = new byte[32];
4566-
var signature = key.SignBIP340(message, new byte[32]);
4567-
4568-
Assert.True(key.CreateXOnlyPubKey().SigVerifyBIP340(signature, message));
4569-
Assert.False(key.CreateXOnlyPubKey().SigVerifyBIP340(signature, new byte[33]));
4570-
}
4571-
45724560
[Fact]
45734561
[Trait("UnitTest", "UnitTest")]
45744562
public void musig_key_sort_vectors()

‎NBitcoin.Tests/util_tests.cs‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -547,18 +547,14 @@ public void CanSplitMoney()
547547
CanSplitMoneyCore(Money.Satoshis(1234), 2);
548548
CanSplitMoneyCore(Money.Satoshis(1234), 10);
549549
CanSplitMoneyCore(Money.Satoshis(1), 3);
550-
CanSplitMoneyCore(Money.Satoshis(-1234), 3);
551-
CanSplitMoneyCore(Money.Satoshis(-1), 3);
550+
Assert.Throws<InvalidOperationException>(() => Money.Satoshis(-1).Split(3).ToArray());
552551
Assert.Throws<ArgumentOutOfRangeException>(() => CanSplitMoneyCore(Money.Satoshis(1000), 0));
553552
CanSplitMoneyCore(Money.Satoshis(0), 10);
554553

555554
var result = Money.Satoshis(20).Split(3).ToArray();
556555
Assert.True(result[0].Satoshi == 7);
557556
Assert.True(result[1].Satoshi == 7);
558557
Assert.True(result[2].Satoshi == 6);
559-
560-
result = Money.Satoshis(-20).Split(3).ToArray();
561-
Assert.Equal(new long[] { -7, -7, -6 }, result.Select(m => m.Satoshi));
562558
}
563559

564560
private void CanSplitMoneyCore(Money money, int parts)
@@ -594,8 +590,7 @@ public void CanSplitAssetMoney()
594590
CanSplitAssetMoneyCore(gold, 1234, 2);
595591
CanSplitAssetMoneyCore(gold, 1234, 10);
596592
CanSplitAssetMoneyCore(gold, 1, 3);
597-
CanSplitAssetMoneyCore(gold, -1234, 3);
598-
CanSplitAssetMoneyCore(gold, -1, 3);
593+
Assert.Throws<InvalidOperationException>(() => new AssetMoney(gold, -1).Split(3).ToArray());
599594
Assert.Throws<ArgumentOutOfRangeException>(() => CanSplitAssetMoneyCore(gold, 1000, 0));
600595
CanSplitAssetMoneyCore(gold, 0, 10);
601596

@@ -604,9 +599,6 @@ public void CanSplitAssetMoney()
604599
Assert.True(result[1].Quantity == 7);
605600
Assert.True(result[2].Quantity == 6);
606601
Assert.True(result[0].Id == gold);
607-
608-
result = new AssetMoney(gold, -20).Split(3).ToArray();
609-
Assert.Equal(new long[] { -7, -7, -6 }, result.Select(m => m.Quantity));
610602
}
611603

612604
private void CanSplitAssetMoneyCore(AssetId asset, long amount, int parts)

‎NBitcoin/Money.cs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,15 @@ public IEnumerable<Money> Split(int parts)
417417
{
418418
if (parts <= 0)
419419
throw new ArgumentOutOfRangeException(nameof(parts), "Parts should be more than 0");
420+
if (_Satoshis < 0)
421+
throw new InvalidOperationException("Cannot split a negative amount");
420422
long remain;
421423
long result = DivRem(_Satoshis, parts, out remain);
422424

423425
for (int i = 0; i < parts; i++)
424426
{
425-
var remainder = Math.Sign(remain);
426-
yield return Money.Satoshis(result + remainder);
427-
remain -= remainder;
427+
yield return Money.Satoshis(result + (remain > 0 ? 1 : 0));
428+
remain--;
428429
}
429430
}
430431

‎NBitcoin/OpenAsset/AssetMoney.cs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,15 @@ public IEnumerable<AssetMoney> Split(int parts)
141141
{
142142
if (parts <= 0)
143143
throw new ArgumentOutOfRangeException("Parts should be more than 0", "parts");
144+
if (_Quantity < 0)
145+
throw new InvalidOperationException("Cannot split a negative amount");
144146
long remain;
145147
long result = DivRem(_Quantity, parts, out remain);
146148

147149
for (int i = 0; i < parts; i++)
148150
{
149-
var remainder = Math.Sign(remain);
150-
yield return new AssetMoney(_Id, result + remainder);
151-
remain -= remainder;
151+
yield return new AssetMoney(_Id, result + (remain > 0 ? 1 : 0));
152+
remain--;
152153
}
153154
}
154155

‎NBitcoin/Secp256k1/ECXOnlyPubKey.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public bool SigVerifyBIP340(SecpSchnorrSignature signature, ReadOnlySpan<byte> m
8585
{
8686
if (signature is null)
8787
return false;
88-
if (msg32.Length != 32)
88+
if (msg32.Length < 32)
8989
return false;
9090
Span<byte> buf = stackalloc byte[32];
9191
SHA256 sha = new SHA256();
@@ -95,7 +95,7 @@ public bool SigVerifyBIP340(SecpSchnorrSignature signature, ReadOnlySpan<byte> m
9595
sha.Write(buf);
9696
Q.x.WriteToSpan(buf);
9797
sha.Write(buf);
98-
sha.Write(msg32);
98+
sha.Write(msg32.Slice(0, 32));
9999
sha.GetHash(buf);
100100
var e = new Scalar(buf, out _);
101101

0 commit comments

Comments
 (0)