-
Notifications
You must be signed in to change notification settings - Fork 849
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4c5b2ac
commit d0b7525
Showing
9 changed files
with
291 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#if HAS_SPAN | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NBitcoin | ||
{ | ||
internal class MusigParticipantPubKeys | ||
{ | ||
public MusigParticipantPubKeys(PubKey aggregated, PubKey[] pubKeys) | ||
{ | ||
if (aggregated is null) | ||
throw new ArgumentNullException(nameof(aggregated)); | ||
if (pubKeys is null) | ||
throw new ArgumentNullException(nameof(pubKeys)); | ||
if (pubKeys.Length is 0) | ||
throw new ArgumentException("pubKeys cannot be an empty collection.", nameof(pubKeys)); | ||
if (aggregated.IsCompressed) | ||
throw new ArgumentException("The aggregated key must be uncompressed.", nameof(aggregated)); | ||
foreach (var pk in pubKeys) | ||
{ | ||
if (pk is null) | ||
throw new ArgumentNullException(nameof(pubKeys), "pubKeys cannot contain null elements."); | ||
if (!pk.IsCompressed) | ||
throw new ArgumentException("All public keys must be compressed.", nameof(pubKeys)); | ||
} | ||
Aggregated = aggregated; | ||
PubKeys = pubKeys; | ||
} | ||
/// <summary> | ||
/// The MuSig2 aggregate plain public key[1] from the KeyAgg algorithm. This key may or may not be in the script directly (as x-only). It may instead be a parent public key from which the public keys in the script were derived. | ||
/// </summary> | ||
public PubKey Aggregated { get; private set; } | ||
|
||
/// <summary> | ||
/// A list of the compressed public keys of the participants in the MuSig2 aggregate key in the order required for aggregation. If sorting was done, then the keys must be in the sorted order. | ||
/// </summary> | ||
public PubKey[] PubKeys { get; private set; } | ||
|
||
internal static MusigParticipantPubKeys Parse(ReadOnlySpan<byte> key, ReadOnlySpan<byte> value) | ||
{ | ||
var agg = new PubKey(key[1..]); | ||
var pubKeys = new PubKey[value.Length / 33]; | ||
int index = 0; | ||
for (int i = 0; i < value.Length; i += 33) | ||
{ | ||
pubKeys[index++] = new PubKey(value.Slice(i, 33)); | ||
} | ||
return new MusigParticipantPubKeys(agg, pubKeys); | ||
} | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#if HAS_SPAN | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NBitcoin | ||
{ | ||
public record MusigTarget(PubKey ParticipantPubKey, PubKey AggregatePubKey, uint256? TapLeaf) : IComparable<MusigTarget> | ||
{ | ||
internal static MusigTarget Parse(ReadOnlySpan<byte> k) | ||
{ | ||
var participant = new PubKey(k[1..]); | ||
if (!participant.IsCompressed) | ||
throw new FormatException("The participant public key must be compressed."); | ||
var agg = new PubKey(k[(1 + 33)..]); | ||
if (!participant.IsCompressed) | ||
throw new FormatException("The aggregate public key must be compressed."); | ||
var tapleaf = k[(1 + 33 + 33)..]; | ||
var h = tapleaf.Length is 0 ? null : new uint256(tapleaf); | ||
return new MusigTarget(participant, agg, h); | ||
} | ||
|
||
public int CompareTo(MusigTarget? other) => other is null ? 1 : PubKeyComparer.Instance.Compare(ParticipantPubKey, other?.ParticipantPubKey); | ||
|
||
public byte[] ToBytes(byte key) | ||
{ | ||
var result = new byte[1 + 33 + 33 + (TapLeaf is null ? 0 : 32)]; | ||
result[0] = key; | ||
ParticipantPubKey.ToBytes(result.AsSpan(1), out _); | ||
ParticipantPubKey.ToBytes(result.AsSpan(1 + 33), out _); | ||
if (TapLeaf is not null) | ||
TapLeaf.ToBytes(result.AsSpan(1 + 33 + 33)); | ||
return result; | ||
} | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#if HAS_SPAN | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NBitcoin | ||
{ | ||
public partial class PSBTInput | ||
{ | ||
public SortedDictionary<PubKey, PubKey[]> MusigParticipantPubKeys { get; } = new SortedDictionary<PubKey, PubKey[]>(PubKeyComparer.Instance); | ||
public SortedDictionary<MusigTarget, byte[]> MusigPubNonces { get; } = new SortedDictionary<MusigTarget, byte[]>(); | ||
public SortedDictionary<MusigTarget, byte[]> MusigPartialSigs { get; } = new SortedDictionary<MusigTarget, byte[]>(); | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#if HAS_SPAN | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace NBitcoin | ||
{ | ||
public partial class PSBTOutput | ||
{ | ||
public SortedDictionary<PubKey, PubKey[]> MusigParticipantPubKeys { get; } = new SortedDictionary<PubKey, PubKey[]>(PubKeyComparer.Instance); | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#if LEGACY_SHIMS | ||
namespace System.Runtime.CompilerServices | ||
{ | ||
internal static class IsExternalInit { } | ||
} | ||
#endif |
Oops, something went wrong.