diff --git a/DotNut.Tests/UnitTest1.cs b/DotNut.Tests/UnitTest1.cs index 7c8f00f..7c1be52 100644 --- a/DotNut.Tests/UnitTest1.cs +++ b/DotNut.Tests/UnitTest1.cs @@ -1001,6 +1001,25 @@ public void Nut13HMACTests() ); } + [Fact] + public void Nut13P2PkTests() + { + var mnemonic = new Mnemonic("half depart obvious quality work element tank gorilla view sugar picture humble"); + string[] keys = + [ + "03381fbf0996b81d49c35bae17a70d71db9a9e802b1af5c2516fc90381f4741e06", + "039bbb7a9cd234da13a113cdd8e037a25c66bbf3a77139d652786a1d7e9d73e600", + "02ffd52ed54761750d75b67342544cc8da8a0994f84c46d546e0ab574dd3651a29", + "02751ab780960ff177c2300e440fddc0850238a78782a1cab7b0ae03c41978d92d", + "0391a9ba1c3caf39ca0536d44419a6ceeda922ee61aa651a72a60171499c02b423" + ]; + for(var i = 0UL; i < (ulong)keys.Length; i++) + { + var privkey = mnemonic.DeriveP2PkPrivkey(i); + Assert.Equal(new PubKey(keys[i]), (PubKey)privkey.Key.CreatePubKey()); + } + } + [Fact] public void NullExpiryTests_PostMintQuoteBolt11Response() { diff --git a/DotNut/NUT13/Nut13.cs b/DotNut/NUT13/Nut13.cs index 4dd7b6f..0ed9400 100644 --- a/DotNut/NUT13/Nut13.cs +++ b/DotNut/NUT13/Nut13.cs @@ -1,7 +1,8 @@ -using System.Security.Cryptography; using DotNut.Abstractions; using DotNut.NBitcoin.BIP39; using NBip32Fast; +using NBitcoin.Secp256k1; +using HMACSHA256 = System.Security.Cryptography.HMACSHA256; namespace DotNut.NUT13; @@ -126,4 +127,18 @@ public static long GetKeysetIdInt(KeysetId keysetId) var mod = (long)Math.Pow(2, 31) - 1; return keysetIdInt % mod; } + + public static PrivKey DeriveP2PkPrivkey(this Mnemonic mnemonic, ulong counter) + { + var seed = mnemonic.DeriveSeed(); + return seed.DeriveP2PkPrivkey(counter); + } + public static PrivKey DeriveP2PkPrivkey(this byte[] seed, ulong counter) + { + var path = (KeyPath) KeyPath.Parse($"m/129372'/10'/0'/0'/{counter}")!; + var pkBytes = BIP32.Instance.DerivePath(path, seed) + .PrivateKey; + + return ECPrivKey.Create(pkBytes); + } }